How to use the Audio with seekbar on Recyclview android?

不想你离开。 提交于 2020-01-07 03:39:09

问题


I am using the lists of audio on my Recyclview and it is working correct means I am able to play the audio file on my Recyclview.

As i am using the Seekbar with my audio file on my Recyclview , the problem is generating that when i am scrolling the Recyclview the other items's of Recyclview Seekbar is changing (Seekbar i am using for the progress of the audio file play.)

What i want that other Seekbar item of Recyclview sholud not be change when i scroll the Recyclview

Please check my code for it ,Inside the onBindViewHolder for my Recyclview , i am using the following code, please check it once.

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

                }
            });

I have visited the following site on SO but did not get the relevant solution
1 .First Link
2. Second Link

Can we use the setTag() and getTag() to get rid of from this problem. I have used the setTag() on my above code. Please check it once.


回答1:


Although, you have asked only about correct SeekBar updates, I am assuming (because you haven't shard complete source) that soon you will face following issues which are linked to the Adapter implementation:

  • How do I remove the seekBar updater, when MediaPlayer completes the playback of audio?
  • How do I release the MediaPlayer when activity is paused?
  • Anonymous View.OnClickListeners and Runnables are being allocated on every onBindViewHolder call. How do I minimize their unnecessary allocation?

You can find complete working solution here - GitHub

Following source tries to fix all above issues. Certain data structures/classes are assumed based on your nomenclature.

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 {

    }
}


来源:https://stackoverflow.com/questions/46150170/how-to-use-the-audio-with-seekbar-on-recyclview-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!