Recyclerview 中的媒体播放器同时播放
media player in recyclerview play at the same
我在回收站视图中使用媒体播放器,问题是当单击不同项目的播放按钮时,它们会同时播放。如何停止上一个并开始新的?
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int position) {
final MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(item.get(position).getAudio());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
viewHolder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.play.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.play.setImageResource(R.drawable.pause);
}
您可以执行以下操作
- 每个视图使用一个全局
MediaPlayer
而不是一个播放器。然后当你点击一个项目时,停止音频,设置一个新的数据源,然后重新启动,即不要在 onBindViewHolder
中每次都创建一个新的 MediaPlayer
实例
MediaPlayer mediaPlayer = new MediaPlayer(); // Somewhere at the top of your code
现在您可以在任何地方直接使用 mediaPlayer
而无需为其分配新实例
2.If 由于某些原因你需要这样做,
你首先要检查是否有一个声音已经在播放,如果有,你应该在用户决定开始一个新的声音时停止它。
viewholder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaplayer.isPlaying ()) {
if (mediaplayer != null){
mediaplayer.stop ();
}
} else {
if (mediaplayer != null) {
mediaplayer.start ();
}
}
}
});
在 setOnCompletionListner 中,如果用户收听了整个声音片段,您将释放声音。
mediaplayer.setOnCompletionListner (new MediaPlayer.OnCompletionListner () {
public void OnCompletion (MediaPlayer mediaplayer) {
mediaplayer.release ();
}
});
我个人会推荐第一种解决方案,因为在这种情况下您的应用程序占用的内存要少得多
这是我的 recyclerView
适配器,您必须将数组列表放入此适配器
public class MyAdapter2 extends RecyclerView.Adapter<MyAdapter2.AudioItemsViewHolder> {
static MediaPlayer mediaPlayer;
Activity activity;
private final ArrayList<GroupItems> audioItems;//change it() to your items
private int currentPlayingPosition;
private final SeekBarUpdater seekBarUpdater;
private AudioItemsViewHolder playingHolder;
public MyAdapter2(Activity activity, ArrayList<GroupItems> items_pro) {
this.audioItems = items_pro;
this.currentPlayingPosition = -1;
seekBarUpdater = new SeekBarUpdater();
this.activity = activity;
}
@Override
public AudioItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//put YourItemsLayout;
return new AudioItemsViewHolder(LayoutInflater.from(parent.getContext()).inflate(YourItemsLayout, parent, false));
}
@Override
public void onBindViewHolder(AudioItemsViewHolder holder, int position) {
if (position == currentPlayingPosition) {
playingHolder = holder;
updatePlayingView();
} else {
updateNonPlayingView(holder);
}
}
private void updateNonPlayingView(AudioItemsViewHolder holder) {
holder.sbProgress.removeCallbacks(seekBarUpdater);
holder.sbProgress.setEnabled(false);
holder.sbProgress.setProgress(0);
holder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
private void updatePlayingView() {
playingHolder.sbProgress.setMax(mediaPlayer.getDuration());
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.setEnabled(true);
if (mediaPlayer.isPlaying()) {
playingHolder.sbProgress.postDelayed(seekBarUpdater, 100);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_pause);
} else {
playingHolder.sbProgress.removeCallbacks(seekBarUpdater);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
}
private class SeekBarUpdater implements Runnable {
@Override
public void run() {
if (null != playingHolder && null != mediaPlayer) {
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.postDelayed(this, 100);
}
}
}
@Override
public int getItemCount() {
return audioItems.size();
}
class AudioItemsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
SeekBar sbProgress;
ImageView ivPlayPause;
AudioItemsViewHolder(View itemView) {
super(itemView);
ivPlayPause = itemView.findViewById(R.id.sound_btn);
ivPlayPause.setOnClickListener(this);
sbProgress = itemView.findViewById(R.id.seekBar);
sbProgress.setOnSeekBarChangeListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.seekBar:
break;
case R.id.sound_btn: {
if (getAdapterPosition() == currentPlayingPosition) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
if (mediaPlayer != null)
mediaPlayer.start();
}
} else {
currentPlayingPosition = getAdapterPosition();
if (mediaPlayer != null) {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
mediaPlayer.release();
}
playingHolder = this;
PlaySound(YOUR AUDIO FILE);//put your audio file
}
if (mediaPlayer != null)
updatePlayingView();
}
break;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
private void PlaySound(File filesound) {
mediaPlayer = MediaPlayer.create(activity, Uri.parse(String.valueOf(filesound)));
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
mediaPlayer.start();
}
private void releaseMediaPlayer() {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
if (outputFile.exists())
outputFile.delete();
mediaPlayer.release();
mediaPlayer = null;
currentPlayingPosition = -1;
}
}
我在回收站视图中使用媒体播放器,问题是当单击不同项目的播放按钮时,它们会同时播放。如何停止上一个并开始新的?
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int position) {
final MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(item.get(position).getAudio());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
viewHolder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.play.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.play.setImageResource(R.drawable.pause);
}
您可以执行以下操作
- 每个视图使用一个全局
MediaPlayer
而不是一个播放器。然后当你点击一个项目时,停止音频,设置一个新的数据源,然后重新启动,即不要在onBindViewHolder
中每次都创建一个新的
MediaPlayer
实例
MediaPlayer mediaPlayer = new MediaPlayer(); // Somewhere at the top of your code
现在您可以在任何地方直接使用 mediaPlayer
而无需为其分配新实例
2.If 由于某些原因你需要这样做,
你首先要检查是否有一个声音已经在播放,如果有,你应该在用户决定开始一个新的声音时停止它。
viewholder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaplayer.isPlaying ()) {
if (mediaplayer != null){
mediaplayer.stop ();
}
} else {
if (mediaplayer != null) {
mediaplayer.start ();
}
}
}
});
在 setOnCompletionListner 中,如果用户收听了整个声音片段,您将释放声音。
mediaplayer.setOnCompletionListner (new MediaPlayer.OnCompletionListner () {
public void OnCompletion (MediaPlayer mediaplayer) {
mediaplayer.release ();
}
});
我个人会推荐第一种解决方案,因为在这种情况下您的应用程序占用的内存要少得多
这是我的 recyclerView
适配器,您必须将数组列表放入此适配器
public class MyAdapter2 extends RecyclerView.Adapter<MyAdapter2.AudioItemsViewHolder> {
static MediaPlayer mediaPlayer;
Activity activity;
private final ArrayList<GroupItems> audioItems;//change it() to your items
private int currentPlayingPosition;
private final SeekBarUpdater seekBarUpdater;
private AudioItemsViewHolder playingHolder;
public MyAdapter2(Activity activity, ArrayList<GroupItems> items_pro) {
this.audioItems = items_pro;
this.currentPlayingPosition = -1;
seekBarUpdater = new SeekBarUpdater();
this.activity = activity;
}
@Override
public AudioItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//put YourItemsLayout;
return new AudioItemsViewHolder(LayoutInflater.from(parent.getContext()).inflate(YourItemsLayout, parent, false));
}
@Override
public void onBindViewHolder(AudioItemsViewHolder holder, int position) {
if (position == currentPlayingPosition) {
playingHolder = holder;
updatePlayingView();
} else {
updateNonPlayingView(holder);
}
}
private void updateNonPlayingView(AudioItemsViewHolder holder) {
holder.sbProgress.removeCallbacks(seekBarUpdater);
holder.sbProgress.setEnabled(false);
holder.sbProgress.setProgress(0);
holder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
private void updatePlayingView() {
playingHolder.sbProgress.setMax(mediaPlayer.getDuration());
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.setEnabled(true);
if (mediaPlayer.isPlaying()) {
playingHolder.sbProgress.postDelayed(seekBarUpdater, 100);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_pause);
} else {
playingHolder.sbProgress.removeCallbacks(seekBarUpdater);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
}
private class SeekBarUpdater implements Runnable {
@Override
public void run() {
if (null != playingHolder && null != mediaPlayer) {
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.postDelayed(this, 100);
}
}
}
@Override
public int getItemCount() {
return audioItems.size();
}
class AudioItemsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
SeekBar sbProgress;
ImageView ivPlayPause;
AudioItemsViewHolder(View itemView) {
super(itemView);
ivPlayPause = itemView.findViewById(R.id.sound_btn);
ivPlayPause.setOnClickListener(this);
sbProgress = itemView.findViewById(R.id.seekBar);
sbProgress.setOnSeekBarChangeListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.seekBar:
break;
case R.id.sound_btn: {
if (getAdapterPosition() == currentPlayingPosition) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
if (mediaPlayer != null)
mediaPlayer.start();
}
} else {
currentPlayingPosition = getAdapterPosition();
if (mediaPlayer != null) {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
mediaPlayer.release();
}
playingHolder = this;
PlaySound(YOUR AUDIO FILE);//put your audio file
}
if (mediaPlayer != null)
updatePlayingView();
}
break;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
private void PlaySound(File filesound) {
mediaPlayer = MediaPlayer.create(activity, Uri.parse(String.valueOf(filesound)));
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
mediaPlayer.start();
}
private void releaseMediaPlayer() {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
if (outputFile.exists())
outputFile.delete();
mediaPlayer.release();
mediaPlayer = null;
currentPlayingPosition = -1;
}
}