自己动手实现音乐播放器app

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;
<
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值