我有一个RecyclerView,其中添加了元素,然后单击它们可以播放声音。如果我在Adapter类中创建所有MediaPlayer方法,则所有内容都会正确释放,并且一次只能播放一个音频。
//this works (code in the adapter class)
private MediaPlayer mMediaPlayer;
//release if not playing
public void releaseMediaPlayer() {
// if no sound is playing
if (mMediaPlayer != null) {
Log.d("rEEEEEEEEEEEEEEEEEEE", "releaseMediaPlayer: ");
mMediaPlayer.release();
mMediaPlayer = null;
}
}
//release media player on sound finish
public MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMediaPlayer();
}
};
// on click listener code
releaseMediaPlayer();
mMediaPlayer = MediaPlayer.create(context, word.getmAudioResourceId());
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(mCompletionListener);
但是,如果我使用单独的类,则每当我调用release方法时,它都不会在一开始就释放,因此会同时播放多种声音。通常会在onCompletion上释放
public class MediaPlay {
private MediaPlayer mMediaPlayer;
public void setmMediaPlayer(MediaPlayer mMediaPlayer) {
this.mMediaPlayer = mMediaPlayer;
}
public MediaPlayer getmMediaPlayer() {
return mMediaPlayer;
}
//release if not playing
public void releaseMediaPlayer() {
// if no sound is playing
if (mMediaPlayer != null) {
Log.d("rEEEEEEEEEEEEEEEEEEEEEEEEEEE", "releaseMediaPlayer: ");
mMediaPlayer.release();
mMediaPlayer = null;
}
}
//release media player on sound finish
public MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMediaPlayer();
}
};
}
使用类时onclicklistener
final MediaPlay m = new MediaPlay();
m.releaseMediaPlayer();
m.setmMediaPlayer(MediaPlayer.create(context, word.getmAudioResourceId()));
m.getmMediaPlayer().start();
m.getmMediaPlayer().setOnCompletionListener(m.mCompletionListener);
我尝试在clickListener之外创建MediaPlay对象,但没有结果。我基本上是想创建一个单独的类,以便可以从我的ACtivities调用它,以便可以将声音停止为onStop方法。 任何输入将不胜感激。
使用点击侦听器编辑1个整个观看者
MediaPlay m;
public ViewHolder(@NonNull View itemView) {
super(itemView);
//play specific sound for each list item
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("ViewHolder: ", String.valueOf(getAdapterPosition()));
Word word = Words.get(getAdapterPosition());
if (word.hasAudio()) {
/*releaseMediaPlayer(); // stop multiple playbacks at once
mMediaPlayer = MediaPlayer.create(context, word.getmAudioResourceId());
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(mCompletionListener); //cleanup*/
if (m != null)
m.releaseMediaPlayer();
m = new MediaPlay();
//m.releaseMediaPlayer(); //TODO still plays duplicate sounds, release method not working when called like this
m.setmMediaPlayer(MediaPlayer.create(context, word.getmAudioResourceId()));
m.getmMediaPlayer().start();
m.getmMediaPlayer().setOnCompletionListener(m.mCompletionListener);
}
}
});
name = itemView.findViewById(R.id.nameT);
type = itemView.findViewById(R.id.typeT);
img = itemView.findViewById(R.id.imgV);
}
答案 0 :(得分:0)
我已经使用回调修改了您的源代码。
请仔细查看MyViewHolder类和MyAdapter的onCreateViewHolder方法:)。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context mContext;
private String[] mDataSet;
private MediaPlayer mMediaPlayer;
public static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mTextView;
private OnMediaPlayRequestedListener mOnMediaPlayRequestedListener;
public MyViewHolder(TextView v, OnMediaPlayRequestedListener listener) {
super(v);
mTextView = v;
mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnMediaPlayRequestedListener != null) {
mOnMediaPlayRequestedListener.onMediaPlayRequested(R.raw.{resource name});
}
}
});
mOnMediaPlayRequestedListener = listener;
}
private interface OnMediaPlayRequestedListener {
void onMediaPlayRequested(int resourceId);
}
}
public MyAdapter(Context context, String[] myDataset) {
mContext = context;
mDataSet = myDataset;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
TextView view =
(TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);
MyViewHolder holder = new MyViewHolder(
view,
new MyViewHolder.OnMediaPlayRequestedListener() {
@Override
public void onMediaPlayRequested(int resourceId) {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
mMediaPlayer = MediaPlayer.create(mContext, resourceId);
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
}
});
return holder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(mDataSet[position]);
}
@Override
public int getItemCount() {
return mDataSet.length;
}
}