MainActivity实现:
1.调用TabHost绑定不同的tags,图标,和content。
mTabHost = (TabHost) findViewById(R.id.mTabHost);
mTabHost.setup();
for (int i = 0; i < titles.length; i++) {//循环添加选项卡
TabHost.TabSpec tabSpec = mTabHost.newTabSpec(tags[i]);//创建一个选项,并指定其标记
View view = getLayoutInflater().inflate(R.layout.tab, null);
TextView titleView = (TextView) view.findViewById(R.id.title);
ImageView iconView = (ImageView) view.findViewById(R.id.icon);
titleView.setText(titles[i]);//设置标题
iconView.setImageResource(icons[i]);//设置图标
tabSpec.setIndicator(view);//为选项设置标题和图标
tabSpec.setContent(R.id.realContent);//为每个选项设置内容
mTabHost.addTab(tabSpec);//将选项添加到选项卡中
}
mTabHost.setOnTabChangedListener(new MyTabChangedListener());//添加选项改变事件处理
mTabHost.setCurrentTab(1);//默认显示第二个
2.切换至不同的按钮时,用新创建的fragment替换之前设置的content,但是我始终没有解决切换fragment后,再回到原fragment状态依然不改变。我初步认定是切换不同tab时,系统会强制将当前创建的fragment销毁。
点击不同tab,显示不同fragemnt
public void onTabChanged(String tabTag){
fragmentTransaction = getFragemntManager().begingTransaction();
if(tabTag.equalsIgnoreCase("artist")){
//切换到艺术家列表
fragmentTransaction.replace(R.id.realContent,new ArtistFragemnt());
}
fragmentTracsaction.commit();//提交事务
}
3.重写ondestroy方法,在退出前保存playlist中的数据
@Override
protected void onDestroy() {
//关闭的时候将播放列表中的数据保存到数据库
mDatabase.execSQL("delete from music_tb");//删除已有的所有数据
for (int i = 0; i < Constants.playlist.size(); i++) {
//循环遍历播放列表中的音乐
Music music = Constants.playlist.get(i);
mDatabase.execSQL("insert into music_tb(title,artist,album,album_id,time,url)values(?,?,?,?,?,?)", new String[]{music.getTitle(), music.getSinger(), music.getAlbum(), music.getAlbum_id() + "", music.getTime() + "", music.getUrl()});
//将音乐信息保存到数据库
}
super.onDestroy();
}
定义一些常量
package com.example.zengqi.musicplayer;
import android.net.Uri;
import java.util.ArrayList;
import java.util.List;
public class Constants {
public static List<Music> musicList = new ArrayList<>();//所有音乐的集合
public static List<Music> playlist = new ArrayList<>();//音乐播放列表
public static final String CONTROL_ACTION = "com.example.zengqi.control";//控制音乐播放动作,即播放或暂停
public static final String SEEKBAR_ACTION = "com.example.zengqi.seekbar";//音乐进度发送变化动作
public static final String COMPLETE_ACTION = "com.example.zengqi.complete";//音乐播放结束动作
public static final String UPDATE_ACTION = "com.example.zengqi.update";//更新进度条
public static final String UPDATE_STYLE = "com.example.zengqi.style";//更新播放形式
public static final Uri ALBUM_URI = Uri.parse("content://media/external/audio/albumart");
public static final String LIST_LOOP = "列表循环";
public static final String SINGLE_LOOP = "单曲循环";
public static final String OVER_FINISH = "结束后暂停";
public static final String RANDOM_PLAY = "随机播放";
public static final int NEW = 6;//开始一首新的音乐
public static final int PLAY = 1;//播放
public static final int PAUSE = 2;//暂停
public static final int ALL_MUSIC = 0x11;//播放所有的音乐
public static final int PLAY_LIST_MUSIC = 0x12;//播放播放列表中的音乐
}
重点是这里使用的musicList和playList,他们是全局状态下的变量,单例模式,用于在不同fragment间通信,所有fragment将值存入其中,同时也从中取值。
public static List<Music> getDataFromDB(SQLiteDatabase db) {
//数据库中未存入size,name的信息
//从数据库中获取播放列表的内容
List<Music> musics = new ArrayList<>();
Cursor cursor = db.rawQuery("select * from music_tb", null);
if (cursor == null || cursor.getCount() == 0) {
return null;
}
while (cursor.moveToNext()) {
Music music = new Music();
music.setTitle(cursor.getString(cursor.getColumnIndex("title")));
music.setSinger(cursor.getString(cursor.getColumnIndex("artist")));
music.setAlbum(cursor.getString(cursor.getColumnIndex("album")));
music.setAlbum_id(cursor.getInt(cursor.getColumnIndex("album_id")));
music.setUrl(cursor.getString(cursor.getColumnIndex("url")));
music.setTime(cursor.getInt(cursor.getColumnIndex("time")));
musics.add(music);
}
return musics;
}
这里注意在每次调用该函数时,都应该检察其值是否为null,例如下面:
if(MusicUtils.getDataFromDB(mDatabase)==null){
Constants.playlist = new ArrayList<>();
}else{
//if与else语法!!!小心!!!
Constants.playlist = MusicUtils.getDataFromDB(mDatabase);//初始化播放列表
}
这样playlist就被合理的初始化了,这样接下来就可以安心调用其方法了,而不会空指针异常。这里需要注意,if与else,我刚开始不够心细,只写了if,导致在从数据库中读取不到playlist的情况下,playlist永远不能够被初始化!
关于MusicService:
package com.example.zengqi.musicplayer;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.Notification.Builder;
<