再次单击同一个 ListView 时如何暂停和恢复音频?

How do I pause and resume audio when clicking again on the same ListView?

我有一个 ListView activity 显示原始文件中的歌曲列表,当我单击其中一个 ListView 时,它会相应地播放歌曲,但如果我第二次单击,它只会重播又是同一首歌。如何在同一曲目上暂停并再次继续播放?以下是我到目前为止完成的代码。

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;

@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) {
            loadTracks();
            Trackmodel track = tracklist[i];

            if (mediaPlayer != null) {
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                    track.setPlaying(false);
                }
            }

            try {
                mediaPlayer = MediaPlayer.create(MainActivity.this, track.getId());
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                    track.setPlaying(false);
                } else {
                    mediaPlayer.start();
                    track.setPlaying(true);
                }

            } 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) {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.reset();
        }
    }
}}

TrackModel.java

package com.example.myapplication;

public class Trackmodel {
private int id;
private String name;
private boolean isPlaying;

public Trackmodel(int id, String name, boolean isPlaying) {
    this.id = id;
    this.name = name;
    this.isPlaying = isPlaying;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public boolean isPlaying() {
    return isPlaying;
}

public void setPlaying(boolean playing) { isPlaying = playing; }
}

TrackAdapter.java

package com.example.myapplication;

import android.content.Context;
import android.view.ContentInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class TrackAdapter extends BaseAdapter {

private Context context;
private Trackmodel[] tracks;

TrackAdapter(Context context, Trackmodel[] tracks) {
    this.context = context;
    this.tracks = tracks;
}

@Override
public int getCount() {
    return tracks.length;
}

@Override
public Object getItem(int i) {
    return tracks[i];
}

@Override
public long getItemId(int i) {
    return i;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    Trackmodel track = (Trackmodel) getItem(i);
    ViewHolder holder;

    if (view == null) {
        view = LayoutInflater.from(context).inflate(R.layout.track_item, viewGroup, false);
        holder = new ViewHolder();
        holder.trackImage = view.findViewById(R.id.track_image);
        holder.titleText = view.findViewById(R.id.track_title);
        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }
    holder.titleText.setText(track.getName());

    if (track.isPlaying()) {
        holder.trackImage.setImageResource(R.drawable.ic_baseline_pause_circle);
    } else {
        holder.trackImage.setImageResource(R.drawable.ic_baseline_play_circle);
    }
    return view;
}

static class ViewHolder {
    ImageView trackImage;
    TextView titleText;
}
}

track_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/sound_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16sp"
android:paddingTop="10dp"
android:paddingRight="16sp">

<ImageView
    android:id="@+id/track_image"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerVertical="true"
    android:padding="5dp"
    app:tint="@android:color/black" />

<TextView
    android:id="@+id/track_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="56dp"
    android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<ListView
    android:id="@+id/musicListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</LinearLayout>

在您的项目点击中,您停止了 MediaPlayer 但之后,您每次都会创建一个新实例。 你有一个 if 检查,它检查 MediaPlayer 是否正在播放并停止它。之后,您创建一个 new MediaPlayer 并再次执行相同的检查。那么当你第一次点击时会发生什么?首先 if 检查没有执行,因为你的 mediaplayer 是空的,它创建一个新的 mediaplayer 并开始播放。 第二次单击后,您的第一个 if 检查正在执行,因为您的 MediaPlayer 不为空且 isPlaying 为真。您停止它,创建 MediaPlayer 的新实例并再次播放。这就是为什么在点击所有下一次后您只需重播歌曲。因为单击时您会停止播放歌曲,创建一个新实例并播放它。

所以你在这里需要什么,我假设你的列表中有不同的曲目,当你点击另一首曲目时,你需要停止上一首曲目并开始新的曲目。但是如果你点击相同的曲目你想暂停它。

在这种情况下,您需要当前曲目 ID playing/played。如果曲目 ID 与正在播放的曲目 ID 相同,则下次单击后,您只需暂停它。如果是另一首曲目,请将其停止并开始新曲目。这是下面的代码,您可以相应地进行更改并将其应用到您的代码中。

int currentTrackId = -1;
    musicListView.setOnItemClickListener(
            (AdapterView.OnItemClickListener) (adapterView, view, i, l) -> {
        loadTracks();
        Trackmodel track = tracklist[i];
        if (currentTrackId != -1 && track.getId() == currentTrackId) {
            // That was the same song, just pause it.
            if (mediaPlayer != null) {
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                    track.setPlaying(false);
                } else {
                    mediaPlayer.start();
                    track.setPlaying(true);
                }
            }
        } else {
            // That's another song, stop the previous one and start the new one
            currentTrackId = track.getId();
            if (mediaPlayer != null) {
                mediaPlayer.stop();
                mediaPlayer.reset();
            }

            try {
                mediaPlayer = MediaPlayer.create(MainActivity.this, track.getId());
                mediaPlayer.start();
                track.setPlaying(true);

            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }  
        }
    });