我有这个RecyclerView,它是器乐节拍的列表,每个项目都包含从Firebase存储检索的器乐名称,制作人名称和音频源。当您单击播放按钮时,它将触发OnClickListener并将数据源设置为该项目的音乐链接的位置,并使用OnPrepareListener播放音频。我遇到的问题是,当我的目标是停止先前的音频并开始新的音频时,如果单击其他项目的播放按钮,它也会播放该音频。这是我的代码:
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
holder.mProducer.setText(tracks.get(position).getProducer());
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.mPlayButton.toggle();
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (mediaPlayer.isPlaying()) {
Log.d("is_playing", "is_playing");
mediaPlayer.stop();
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
} else {
mediaPlayer.start();
}
}
});
mediaPlayer.prepareAsync();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
Log.d("released", "released");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Toast.makeText(context, Integer.toString(tracks.size()), Toast.LENGTH_SHORT).show();
}
});
}
答案 0 :(得分:2)
每个视图使用单个全局MediaPlayer,而不是播放器。然后,当您单击一个项目时,停止音频,设置新的数据源,然后重新启动。
总的来说,使用多个MediaPlayers是一个坏主意,因为这些东西会占用大量内存。因此,您当前的代码非常糟糕。在每个绑定上创建一个新的绑定会浪费大量内存,并可能导致滚动缓慢。