前言:大概一周多以前(现在是2018.11.26 15:24)android平台开发的课程结束了,要写大作业,最后决定写这个音乐播放器,因为老师在课堂上讲的例子也是这个,前面的作业也把一些东西实现了,我就打算把功能都做出来,UI搞得稍微好看一些。
还有很多想法没实现,奈何期末考试临近所以先做成这个样子把作业交了。
先上图,目前实现情况:
1.首先需要一个Song类用来存储每一个歌曲对像,含参构造函数为
public Song(long id,
long album_id,
int song_list_id,
int song_imageidid,
String song_name,
String song_author,
String song_addr,
long duration,
int isMusic,
String album) {
this.id = id;
this.album_id = album_id;//专辑id
this.song_list_id = song_list_id;在歌曲list中的位置
this.song_imageid = song_imageidid;//后面在song_item布局中会用到的图片的id
this.song_name = song_name;//歌曲名字
this.song_author = song_author;//歌手
this.song_addr = song_addr;//文件位置
this.duration = duration;//歌曲时长
this.isMusic = isMusic;//是否是music
this.album = album;//专辑
}
2.然后是登录界面,这个界面是这个应用的主activity,背景是实现的动态背景,加载的MP4文件,视频来源抖音,我自己用pr剪辑的,不太会用pr所以就随便剪辑了一下将就用了。
2.1动态背景:整个布局最外层使用的FrameLayout, orientation设置为vetical
<xxx.xxxx.xxxx.musciplayer.dynamicBackGround.VideoBackground
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
注:xxx.xxxx.xxx是我建立工程时设置的Company domain,不想被看到就换成了x
这一段就是动态背景,接着建立VideoBackground类,继承自VideoView类
public class VideoBackground extends VideoView {
public VideoBackground(Context context) {
super(context);
}
public VideoBackground(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VideoBackground(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//重写onMeasure方法,为了更好的自适应全屏幕
//作用是返回一个默认的值,如果MeasureSpec没有强制限制的话则使用提供的大小.
// 否则在允许范围内可任意指定大小
//第一个参数size为提供的默认大小,第二个参数为测量的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//我们重新计算高度
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
}
}
在主activity对应的类中实现方法initbackground()方法:
public void initBackground() {
//找VideoView控件
videoBackground = findViewById(R.id.videoview); //加载视频布局
videoBackground.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.stars));
// 播放
videoBackground.start();
//循环播放 设置一个在媒体文件播放完毕,到达终点时调用的回调
videoBackground.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
videoBackground.start();
}
});
}
注:视频文件放在raw文件夹下,这个文件夹被新建且处于res目录中
2.2 用户名输入框和密码输入框——两个EditText控件
我给他们实现了边框,这需要自定义布局文件,设置solid(影响背景颜色)、corners(影响边框边缘弧度)、stroke(可影响边框线宽度和颜色),使用android:backgroundddi调用自定义布局文件即可
设置android:singleLine可以设置输入为单行输入
设置android:inputType="numberPassword"可以设置输入为数字密码
android:padding设置内边距可以使得字体和边缘看起来不那么拥挤
2.3 记住用户名和记住密码单选框——两个CheckBox控件
android:checked="true"可以使得单选框默认选中
2.4 登录按钮——Button
同样实现了自定义布局文件更改背景和边框样式
2.5 登录界面的整体布局结构
2.6 登录界面的逻辑
写了三个方法:
initButtonDeal();//处理登录按钮的事件
initBackground();//初始化动态背景
dealCheckBox();//处理复选框相关事件,有部分在匹配密码后处理
2.6.1 initButtonDeal() 处理登录按钮的点击事件,即判断密码是否正确,保存到本地等操作
SharedPreferences.Editor editor,editor_pas;
editor = getSharedPreferences("username_data", MODE_PRIVATE).edit();
editor_pas = getSharedPreferences("password_data", MODE_PRIVATE).edit();
在这里用SharedPreferences使用键值对的方式来存储数据,
调用putString()存入字符串数据,调用apply()将数据提交,调用clear()清除数据
MODE_PRIVATE是默认的操作模式,和直接传入0效果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写
可以用isChecked()获取CheckBox状态,得知是否勾选了记住用户名或者记住密码
同时检测密码正确后会跳转至第二个activity,并且将当前的用户名数据传过去
这采用显式Intent实现
Intent intent = new Intent(LoginActivity.this, DisplayActivity.class);
intent.putExtra("userName", userStr);
startActivity(intent);
如果密码不正确则弹出消息要求重试
2.6.2 dealCheckBox()处理的事件是在启动程序时去检测本地有没有以前保存的用户名数据和密码数据,如果有就加载。
//加载默认用户名
SharedPreferences pref = getSharedPreferences("username_data", MODE_PRIVATE);
String default_name = pref.getString("name", "");
if (!default_name.isEmpty()) {
user.setText(default_name);
}
加载密码操作同上
2.6.3 initBackground() 初始化动态背景
首先把视频布局实例化对象,然后使用setVideoURI设置具体视频文件,例:
Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.stars
使用start()方法启动,setOnCompletionListener设置一个在媒体文件播放完毕,到达终点时调用的回调
同时要注意重写Restart()方法防止重新加载这个activity时黑屏
重写onStop()方法调用 stopPlayback() 防止切出屏幕时背景音乐还在播放
后面的内容见下一篇