如何在Recyclview android上使用带有seekbar的音频?

Rav*_*aha 0 android android-mediaplayer android-seekbar recycler-adapter

我使用的是我的音频列表,Recyclview并且工作正常,这意味着我可以播放音频文件Recyclview

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

当我滚动时,我想要的其他Seekbar项目Recyclview不会改变Recyclview

请检查我的代码吧,里面的onBindViewHolderRecyclview,我使用下面的代码,请一次检查。

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

                }
            });
Run Code Online (Sandbox Code Playgroud)

我已经访问了SO上的以下站点,但未获得相关的解决方案
1.第一链接
2.第二链接

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

kuj*_*iti 5

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

  • MediaPlayer完成音频播放后,如何删除seekBar更新器?
  • 我该如何释放 MediaPlayer活动暂停的时间?
  • 匿名View.OnClickListeners和Runnables分配给每个 onBindViewHolder呼叫。如何减少不必要的分配?

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

以下消息源尝试解决所有上述问题。根据您的命名法假定某些数据结构/类。

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 {

    }
}
Run Code Online (Sandbox Code Playgroud)