再次单击同一个 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());
}
}
});
我有一个 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());
}
}
});