如何在 Recyclerview android 中使用带搜索栏的音频?

How to use the Audio with seekbar on Recyclview android?

我正在 Recyclview 上使用音频列表,它工作正常意味着我可以在 上播放音频文件Recyclview.

因为我在 Recyclview 上使用 Seekbar 和我的音频文件,问题是生成当我滚动 Recyclview 时另一个 items's of Recyclview Seekbar 正在改变(Seekbar 我正在使用进度音频文件播放。)

我想要 Recyclview 的其他 Seekbar 项在我滚动Recyclview

请检查我的代码,在我的 RecyclviewonBindViewHolder 中,我正在使用以下代码,请检查一次

 ((MyAudioChat) holder).sbMyAudio.setTag(position);
            ((MyAudioChat) holder).imgPlayAudio.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ((MyAudioChat) holder).sbMyAudio.removeCallbacks(null);
                    ((MyAudioChat) holder).sbMyAudio.setProgress(0);
                    if (mediaPlayer == null) {
                        mediaPlayer();
                        ((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration());
                    } else {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        mediaPlayer();
                        ((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration());
                    }

                    ((MyAudioChat) holder).sbMyAudio.getTag();
                    ((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration()); // Set the Maximum range of the
                    ((MyAudioChat) holder).sbMyAudio.setProgress(mediaPlayer.getCurrentPosition());// set current progress to song's
                    Runnable moveSeekBarThread = new Runnable() {
                        public void run() {
                            if (mediaPlayer.isPlaying()) {

                                int mediaPos_new = mediaPlayer.getCurrentPosition();
                                int mediaMax_new = mediaPlayer.getDuration();
                                ((MyAudioChat) holder).sbMyAudio.setMax(mediaMax_new);
                                ((MyAudioChat) holder).sbMyAudio.setProgress(mediaPos_new);
                                ((MyAudioChat) holder).sbMyAudio.postDelayed(this, 100); //Looping the thread after 0.1 second
                                ((MyAudioChat) holder).sbMyAudio.getTag();
                            }

                        }
                    };

                    ((MyAudioChat) holder).sbMyAudio.removeCallbacks(moveSeekBarThread);
                    ((MyAudioChat) holder).sbMyAudio.postDelayed(moveSeekBarThread, 100);

                }
            });

我在SO上访问了以下站点,但没有得到相关的解决方案
1 .First Link
2. Second Link

我们可以使用 setTag()getTag() 来摆脱这个问题吗?我在上面的代码中使用了 setTag() 。请检查一次。

尽管您只询问了正确的 SeekBar 更新,但我假设(因为您还没有分片完整的源代码)很快您将面临以下问题链接到 Adapter 实现:

  • 如何在 MediaPlayer 完成音频播放后删除 seekBar 更新程序?
  • activity暂停时如何释放MediaPlayer
  • 匿名 View.OnClickListeners 和 Runnables 被分配到 every onBindViewHolder 呼叫。我如何尽量减少他们不必要的分配?

您可以在此处找到完整的工作解决方案 - GitHub

以下来源试图解决上述所有问题。某些数据 structures/classes 是根据您的命名法假定的。

public class MainActivity extends Activity {

    private MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(this));
        AudioChat audioChats[] = new AudioChat[128];
        rv.setAdapter(new MyAdapter(Arrays.asList(audioChats)));

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (null != mediaPlayer) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyAudioChat> {

        private List<AudioChat> audioChats;
        private int currentPlayingPosition;
        private SeekBarUpdater seekBarUpdater;

        MyAdapter(List<AudioChat> audioChats) {
            this.audioChats = audioChats;
            this.currentPlayingPosition = -1;
            seekBarUpdater = new SeekBarUpdater();
        }

        @Override
        public MyAudioChat onCreateViewHolder(ViewGroup parent, int viewType) {
            return new MyAudioChat(LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false));
        }

        @Override
        public void onBindViewHolder(MyAudioChat holder, int position) {
            if (position == currentPlayingPosition) {
                seekBarUpdater.playingHolder = holder;
                holder.sbMyAudio.post(seekBarUpdater);
            } else {
                holder.sbMyAudio.removeCallbacks(seekBarUpdater);
                holder.sbMyAudio.setProgress(0);
            }
        }

        private class SeekBarUpdater implements Runnable {
            MyAudioChat playingHolder;

            @Override
            public void run() {
                if (null != mediaPlayer && playingHolder.getAdapterPosition() == currentPlayingPosition) {
                    playingHolder.sbMyAudio.setMax(mediaPlayer.getDuration());
                    playingHolder.sbMyAudio.setProgress(mediaPlayer.getCurrentPosition());
                    playingHolder.sbMyAudio.postDelayed(this, 100);
                } else {
                    playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
                }
            }
        }

        @Override
        public int getItemCount() {
            return audioChats.size();
        }

        class MyAudioChat extends RecyclerView.ViewHolder implements View.OnClickListener {
            SeekBar sbMyAudio;
            ImageView imgPlayAudio;

            MyAudioChat(View itemView) {
                super(itemView);
                imgPlayAudio = (ImageView) itemView.findViewById(R.id.imgPlayAudio);
                imgPlayAudio.setOnClickListener(this);
                sbMyAudio = (SeekBar) itemView.findViewById(R.id.sbMyAudio);
            }

            @Override
            public void onClick(View v) {
                currentPlayingPosition = getAdapterPosition();
                if (mediaPlayer != null) {
                    if (null != seekBarUpdater.playingHolder) {
                        seekBarUpdater.playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
                        seekBarUpdater.playingHolder.sbMyAudio.setProgress(0);
                    }
                    mediaPlayer.release();
                }
                seekBarUpdater.playingHolder = this;
                startMediaPlayer();
                sbMyAudio.setMax(mediaPlayer.getDuration());
                sbMyAudio.post(seekBarUpdater);
            }
        }

        private void startMediaPlayer() {
            mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.mp3);
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    seekBarUpdater.playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
                    seekBarUpdater.playingHolder.sbMyAudio.setProgress(0);
                    mediaPlayer.release();
                    mediaPlayer = null;
                    currentPlayingPosition = -1;
                }
            });
            mediaPlayer.start();
        }
    }

    private class AudioChat {

    }
}