媒体播放器在循环视图播放相同



我在回收器视图中使用媒体播放器,问题是当不同项目的播放按钮被点击时,它们都在同一时间播放。我怎样才能停止以前的工作,开始新的工作呢?

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);
}

这是我的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;
}
}

你可以这样做

  1. 使用单个全局MediaPlayer而不是每个视图一个玩家。然后,当你点击一个项目,停止音频,设置一个新的数据源,并重新启动,即不创建一个新的MediaPlayer实例每次在onBindViewHolder
MediaPlayer mediaPlayer = new MediaPlayer(); // Somewhere at the top of your code

现在你可以在任何地方直接使用mediaPlayer,而不需要为这个

分配一个新的实例2。如果出于某种原因您需要这样做,

你首先要检查是否有一个声音已经在播放,如果有,你应该在用户决定开始一个新的声音时停止它。

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 ();
}
}
}
});

在setoncompletionlistener中,如果用户收听整个声音剪辑,则释放声音。

mediaplayer.setOnCompletionListner (new MediaPlayer.OnCompletionListner () {
public void OnCompletion (MediaPlayer mediaplayer) {
mediaplayer.release ();
}
});

我个人推荐第一种解决方案,因为在这种情况下,应用程序占用的内存要少得多

最新更新