Android ListView点击同一项实现音频暂停与恢复的方法
问题根源
你现有代码无法实现同项点击暂停/恢复的核心原因有3点:
- 每次列表项点击事件触发时都会调用
loadTracks(),该方法会重新初始化所有歌曲数据对象,直接清空之前保存的播放状态 - 没有记录当前激活的音轨位置,无法区分点击的是当前正在操作的音轨还是其他音轨
- 音频控制逻辑错误:使用
stop()/reset()做状态切换,实际上暂停操作应该调用pause(),暂停状态下直接调用start()即可从断点恢复播放,不需要重置播放器;且每次点击都新建MediaPlayer实例,既无法保留播放进度,还会造成内存泄漏
修改步骤
- 首先在
MainActivity中新增全局变量,记录当前正在操作的音轨位置,初始值设为-1代表无激活音轨:
private int currentActivePosition = -1;
- 删除
onItemClick方法开头调用的loadTracks(),该方法仅需在onCreate中执行一次初始化列表即可 - 重写列表项点击的逻辑,分场景处理播放状态:
- 若点击项为当前激活项:判断播放器状态,正在播放则暂停,暂停中则恢复播放
- 若点击项为其他音轨:先释放旧播放器资源,重置旧音轨的播放状态,再为新音轨创建播放器开始播放
- 修改
onDestroy生命周期逻辑,播放器销毁时调用release()彻底释放资源,避免内存泄漏 - (可选)删除
TrackAdapter中无用的import android.view.ContentInfo;导入,不影响功能但可以清理冗余代码
修改后的完整MainActivity.java代码
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; public class MainActivity extends AppCompatActivity { private ListView musicListView; private Trackmodel[] tracklist; private TrackAdapter adapter; private MediaPlayer mediaPlayer; // 记录当前激活的音轨位置,-1代表无播放/暂停的音轨 private int currentActivePosition = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); musicListView = findViewById(R.id.musicListView); loadTracks(); musicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Trackmodel selectedTrack = tracklist[i]; try { // 点击的是当前已经激活的音轨(正在播放/暂停) if (i == currentActivePosition && mediaPlayer != null) { if (mediaPlayer.isPlaying()) { // 正在播放则暂停 mediaPlayer.pause(); selectedTrack.setPlaying(false); } else { // 暂停状态则恢复播放 mediaPlayer.start(); selectedTrack.setPlaying(true); } } else { // 点击的是新的音轨,先释放旧播放器资源 if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; // 重置旧激活音轨的状态 tracklist[currentActivePosition].setPlaying(false); } // 创建新播放器播放选中音轨 mediaPlayer = MediaPlayer.create(MainActivity.this, selectedTrack.getId()); mediaPlayer.start(); selectedTrack.setPlaying(true); // 更新当前激活位置 currentActivePosition = i; } // 刷新列表更新播放/暂停图标 adapter.notifyDataSetChanged(); } catch (Exception e) { Log.e("Exception", e.getMessage()); } } }); } public void loadTracks() { tracklist = new Trackmodel[]{ new Trackmodel(R.raw.decode, "Paramore - Decode", false), new Trackmodel(R.raw.thats_what_you_get, "Paramore - That's What You Get", false), new Trackmodel(R.raw.starstrukk, "30H!3 - Starstrukk", false), new Trackmodel(R.raw.we_are_young, "30H!3 - We Are Young", false) }; adapter = new TrackAdapter(MainActivity.this, tracklist); musicListView.setAdapter(adapter); adapter.notifyDataSetChanged(); } @Override protected void onDestroy() { super.onDestroy(); if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } } }
其余类(Trackmodel、TrackAdapter、布局文件)不需要修改即可实现需求:点击同一项可以切换播放/暂停,点击其他项会自动停止当前播放的歌曲、切换到新选中的歌曲播放,列表左侧的图标也会同步对应播放/暂停状态。
内容的提问来源于stack exchange,提问作者sdwd23
相关产品推荐
相关产品推荐

