一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android开发:在线音频播放器实现之第二章PlayActivity页面详解

时间:2026-05-31 09:30:01 编辑:袖梨 来源:一聚教程网

本文将详细解析音频播放器UI页面的核心实现要点,包括网络、封面动画、播放状态管理等关键技术细节,为开发者提供实用参考。

背景:该播放器支持专辑播放功能,具备歌曲列表、播放控制、收藏、倍速调节等常见功能,与主流音乐应用功能相似。

1、网络权限与实现

"android.permission.INTERNET" />IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    registerReceiver(networkReceiver, filter, Context.RECEIVER_EXPORTED);
}else {
    registerReceiver(networkReceiver, filter);
}
boolean isNetWork = false;private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
            isNetWork = JxwApplication.isNetwork();
            if(isNetWork){ //有网
                if (netWorkDialog != null && netWorkDialog.isShowing()) {
                    netWorkDialog.dismiss();//隐藏无网弹窗
                }
            }else {//无网
                if(netWorkDialog!=null){
                    netWorkDialog.show(); //显示无网弹窗
                }
                animatorSet.pause(); //暂停封面旋转
            }
        }
    }
};

2、专辑封面旋转动画

AnimatorSet animatorSet;
private String book_cover; //专辑封面//==========在onCreate 中===================
 RequestOptions options = new RequestOptions();//图片圆角
        Glide.with(ReadTextActivity.this).load(book_cover)
                .placeholder(R.mipmap.img_med_player_placeholder) // 占位图资源ID
                .error(R.mipmap.img_med_player_placeholder) // 错误占位图资源ID
                .apply(options).into(mBinding.ivCover);animatorSet = new AnimatorSet();
        ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(mBinding.ivCover, "rotation", 0f, 360f);
        rotateAnimator.setInterpolator(new LinearInterpolator());
        rotateAnimator.setDuration(10000);
        rotateAnimator.setRepeatCount(Animation.INFINITE);
        rotateAnimator.setRepeatMode(ValueAnimator.RESTART);
        animatorSet.playTogether(rotateAnimator);
        animatorSet.start();
        animatorSet.pause();//====================播放====================
animatorSet.resume();
//====================暂停====================
animatorSet.pause();//==========在onDestroy 中===================
if (animatorSet != null) {
            animatorSet.cancel();
            animatorSet = null;
        }

3、播放状态变量管理

private String book_cover; //专辑封面
private String book_name;
private int bookId;
private boolean isCollect = false; //是否收藏
private String unit_name; //正在播放的歌曲名称
public static float speed = 1f; //预选 播放速度
public static int loop_type = 0; // 0顺序播放  1单篇循环  2随机播放
public static boolean isplay = true; //播放状态
private String jsonList; //播放的歌曲列表数据
private int pre_gb_time = 0; //定时播放的时间 0/15/30/45分钟

4、基于EventBus的消息通信机制

//引用
implementation 'org.greenrobot:eventbus:3.2.0'//=============在onCreate() 中注册===============
EventBus.getDefault().register(this);//=============在onDestroy()中注销===============
// 针对性移除所有粘性事件类型(与订阅方法对应)
        EventBus.getDefault().removeStickyEvent(PlayTimeShowMsg.class);
        EventBus.getDefault().removeStickyEvent(PoiToUIMsg.class);
        EventBus.getDefault().removeStickyEvent(PlayUnitPoiMsg.class);
        EventBus.getDefault().removeStickyEvent(PlayShowPoiMsg.class);
        EventBus.getDefault().removeStickyEvent(PlayStateMsg.class);
        EventBus.getDefault().removeStickyEvent(RequestMsg.class);
        EventBus.getDefault().removeStickyEvent(PlayInfoMsg.class);
// 最后注销订阅
EventBus.getDefault().unregister(this);//===========发送播放消息============
//封装成工具类 可从任何地方调用 比如通知栏或控制栏的自定义UI中实现控制播放
public class PlayControlMsg {    public static final String YYTS_ACTION_PAUSE = "YYTS_ACTION_PAUSE";//暂停
    public static final String YYTS_ACTION_PLAY = "YYTS_ACTION_PLAY";//播放
    public static final String YYTS_PLAY_NEXT = "YYTS_PLAY_NEXT";//播放下一个
    public static final String YYTS_PLAY_PREVIOUS = "YYTS_PLAY_PREVIOUS";//播放上一个    public String msg;    public String getMsg() {
        return msg;
    }    public void setMsg(String msg) {
        this.msg = msg;
    }
}
public class PlayControlTools {    public static void setACTION_PAUSE(){//暂停
        PlayControlMsg msg = new PlayControlMsg();
        msg.setMsg(PlayControlMsg.YYTS_ACTION_PAUSE);
        EventBus.getDefault().post(msg);
    }    public static void setACTION_PLAY(){//播放
        PlayControlMsg msg = new PlayControlMsg();
        msg.setMsg(PlayControlMsg.YYTS_ACTION_PLAY);
        EventBus.getDefault().post(msg);
    }    public static void setPLAY_PREVIOUS(){ //上一个
        PlayControlMsg msg = new PlayControlMsg();
        msg.setMsg(PlayControlMsg.YYTS_PLAY_PREVIOUS);
        EventBus.getDefault().post(msg);
    }    public static void setPLAY_NEXT(){ //下一个
        PlayControlMsg msg = new PlayControlMsg();
        msg.setMsg(PlayControlMsg.YYTS_PLAY_NEXT);
        EventBus.getDefault().post(msg);
    }
}//UI页滑动进度的 和消息发送
mBinding.seekbar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { }            @Override
            public void onStartTrackingTouch(SeekBar seekBar) { }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
//                Log.e("TAG","进度条,当前值:"+seekBar.getProgress());
//                mBinding.ivReadBf.setImageResource(R.mipmap.icon_pause);
                PoiToPlayMsg.sendMsg(seekBar.getProgress()); //发送指针
            }
        });
//=============接收播放消息================
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveTime(PlayTimeShowMsg msg) { //接收时间显示 定时播放的倒计时
        mBinding.tvPlayTime.setText(ConstantFd.FormatMiss(msg.getTime()));
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveProcess(PoiToUIMsg msg) { //接收进度
//        Log.i("TAG", "process: "+msg.getPoi());
//        Log.i("TAG", "getMax: "+msg.getMax());
        mBinding.seekbar1.setMax((int)msg.getMax());
        mBinding.seekbar1.setProgress((int)msg.getPoi());
        if(msg.getPoi()<=msg.getMax()){
            //将int类型 进度转为String的 为分:秒 显示
            mBinding.tvNum1.setText(ConstantFd.FormatMiss(msg.getPoi())); 
        }else {
            mBinding.tvNum1.setText(ConstantFd.FormatMiss(msg.getMax()));
        }
        mBinding.tvNum2.setText(ConstantFd.FormatMiss(msg.getMax()));
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receivePlayPoi(PlayUnitPoiMsg msg) { //接收单元指针
        Log.i("TAG", "单元指针poi: "+msg.getPoi());
        mUnitAdapter.mPosSomeTime = msg.getPoi(); //适配器播放指针更新
        getCollectState(); //获取收藏状态
        updatePlayUI(); //刷新列表ui
        playOrPauseUI(); //播放ui和动画更新
        mBinding.recyclerView.smoothScrollToPosition(msg.getPoi()); //列表滚动到指定位置
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receivePlayPoi(PlayShowPoiMsg msg) { //接收单元指针
        Log.i("TAG", "单元指针poi: "+msg.getPoi());
        mUnitAdapter.mPosSomeTime = msg.getPoi();//适配器播放指针更新
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receivePlayState(PlayStateMsg msg) { //接收播放状态
        playOrPauseUI(); //播放状态ui更新
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveEventBus(RequestMsg msg) { //数据请求中
        if(!isFinishing()){
            mBinding.loading.setVisibility(View.VISIBLE);
        }
    }    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveEventBus(PlayInfoMsg msg) {
        mBinding.loading.setVisibility(View.GONE);
         if(ConstantFd.unit_List.size() > 0 && mUnitAdapter!=null){ 
                mUnitAdapter.updateData(ConstantFd.unit_List);//适配器数据更新
                updatePlayUI(); //更新播放器ui 指针显示等
            }    }//================消息封装类===================
/**
 * 歌曲播放进度
 */
public class PoiToPlayMsg { //UI->服务
    long poi; //当前指针    public long getPoi() {
        return poi;
    }    public void setPoi(long poi) {
        this.poi = poi;
    }
    public static void sendMsg(long poi){
        PoiToPlayMsg msg = new PoiToPlayMsg();
        msg.setPoi(poi);
        EventBus.getDefault().post(msg); //发送指针
    }
}/**
 * 歌曲播放进度
 */
public class PoiToUIMsg { //服务->UI
    long poi; //当前指针
    long max; //最大指针    public long getPoi() {
        return poi;
    }    public void setPoi(long poi) {
        this.poi = poi;
    }    public long getMax() {
        return max;
    }    public void setMax(long max) {
        this.max = max;
    }    public static
                        

相关文章