You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android RecyclerView使用MediaPlayer多音频同时播放如何解决

解决方案

核心逻辑

用成员变量标记当前正在播放的列表项位置,切换播放项前先停止上一个MediaPlayer的播放任务,同时刷新上下两个播放项的按钮UI,避免状态错乱。

改造后代码

1. 新增标记位成员变量

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>  {
    // 全局唯一MediaPlayer实例,保证同一时间只有一个音频播放
    private final MediaPlayer mediaPlayer = new MediaPlayer();
    // 标记位:记录当前正在播放的列表项下标,默认-1代表无正在播放的音频
    private int currentPlayingPosition = -1;

2. 修改onBindViewHolder逻辑

不要在onBindViewHolder中直接操作MediaPlayer重置/设置数据源,将音频加载逻辑移到点击事件中:

@Override
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int position) {
    // 绑定阶段先根据当前播放标记设置按钮显示状态
    viewHolder.play.setImageResource(currentPlayingPosition == position ? R.drawable.pause : R.drawable.play);

    viewHolder.play.setOnClickListener(v -> {
        int clickPosition = viewHolder.getAdapterPosition();
        // 防止列表项已被移除时的无效点击
        if (clickPosition == RecyclerView.NO_POSITION) return;

        // 点击的是正在播放的项,切换暂停/播放状态
        if (currentPlayingPosition == clickPosition) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                viewHolder.play.setImageResource(R.drawable.play);
            } else {
                mediaPlayer.start();
                viewHolder.play.setImageResource(R.drawable.pause);
            }
            return;
        }

        // 点击的是新项:先停止上一个播放,重置状态
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.reset();
            // 刷新上一个播放项的按钮UI
            int lastPlayPos = currentPlayingPosition;
            currentPlayingPosition = -1;
            notifyItemChanged(lastPlayPos);
        }

        // 加载新音频并播放
        try {
            mediaPlayer.setDataSource(item.get(clickPosition).getAudio());
            mediaPlayer.prepare();
            mediaPlayer.start();
            // 更新标记位和当前项按钮状态
            currentPlayingPosition = clickPosition;
            viewHolder.play.setImageResource(R.drawable.pause);
        } catch (IOException e) {
            e.printStackTrace();
            currentPlayingPosition = -1;
            viewHolder.play.setImageResource(R.drawable.play);
        }
    });
}

注意事项

  • 页面销毁时需调用mediaPlayer.release()释放MediaPlayer资源,避免内存泄漏
  • 若音频文件过大或为网络音频,建议将prepare()替换为prepareAsync(),配合OnPreparedListener回调完成后再调用start(),避免阻塞主线程
  • 可给MediaPlayer设置OnCompletionListener,音频播放完成后重置currentPlayingPosition为-1并刷新对应项UI

内容的提问来源于stack exchange,提问作者ghazalia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:51:03