在RecyclerView切换音频源中处理MediaPlayer时遇到麻烦

时间:2018-09-12 16:09:36

标签: android android-recyclerview android-mediaplayer android-viewholder

我有这个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();
        }
    });
}

下图显示了项目列表,黄色表示正在播放音乐,黑色表示未播放: enter image description here

1 个答案:

答案 0 :(得分:2)

每个视图使用单个全局MediaPlayer,而不是播放器。然后,当您单击一个项目时,停止音频,设置新的数据源,然后重新启动。

总的来说,使用多个MediaPlayers是一个坏主意,因为这些东西会占用大量内存。因此,您当前的代码非常糟糕。在每个绑定上创建一个新的绑定会浪费大量内存,并可能导致滚动缓慢。