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

Android ListView点击同一项实现音频暂停与恢复的方法

问题根源

你现有代码无法实现同项点击暂停/恢复的核心原因有3点:

  • 每次列表项点击事件触发时都会调用loadTracks(),该方法会重新初始化所有歌曲数据对象,直接清空之前保存的播放状态
  • 没有记录当前激活的音轨位置,无法区分点击的是当前正在操作的音轨还是其他音轨
  • 音频控制逻辑错误:使用stop()/reset()做状态切换,实际上暂停操作应该调用pause(),暂停状态下直接调用start()即可从断点恢复播放,不需要重置播放器;且每次点击都新建MediaPlayer实例,既无法保留播放进度,还会造成内存泄漏
修改步骤
  1. 首先在MainActivity中新增全局变量,记录当前正在操作的音轨位置,初始值设为-1代表无激活音轨:
private int currentActivePosition = -1;
  1. 删除onItemClick方法开头调用的loadTracks(),该方法仅需在onCreate中执行一次初始化列表即可
  2. 重写列表项点击的逻辑,分场景处理播放状态:
    • 若点击项为当前激活项:判断播放器状态,正在播放则暂停,暂停中则恢复播放
    • 若点击项为其他音轨:先释放旧播放器资源,重置旧音轨的播放状态,再为新音轨创建播放器开始播放
  3. 修改onDestroy生命周期逻辑,播放器销毁时调用release()彻底释放资源,避免内存泄漏
  4. (可选)删除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:03:26