Recyclerview viewholder possible to change views at other adapter positions (not current position)?

10,293

In your adapter have an int variable to maintain which position is being played

int mCurrentPlayingPosition = -1; // if -1 nothing is playing

in your play button's on click listener, do this

PlayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int PlayStopButtonState = (int) PlayButton.getTag();

                int previousPosition = mCurrentPlayingPosition;
                if (PlayStopButtonState == 1) {

                    mCurrentPlayingPosition = getAdapterPosition();

                    mVideoAudioCallbacks.onClick(100 + getAdapterPosition());
                    PlayButton.setImageResource(R.drawable.playstop);
                    PlayButton.setTag(2);

                } else {
                    mCurrentPlayingPosition = -1; // nothing wil be played after hitting stop
                    mVideoAudioCallbacks.onClick(200 + getAdapterPosition());
                    PlayButton.setImageResource(R.drawable.playarrow);
                    PlayButton.setTag(1);
                }

                if(previousPosition != -1)
                    notifyItemChanged(previousPosition);

            }
        });

in your onBindViewHolder do the following

@Override
public void onBindViewHolder(AddVideoAudioViewHolder holder, int position) {
    if(mCurrentPlayingPosition == position ){
       // display stop icon
    } else {
       // display play icon
    }
}
Share:
10,293
Nicholas Muir
Author by

Nicholas Muir

Updated on June 13, 2022

Comments

  • Nicholas Muir
    Nicholas Muir about 2 years

    I have a recyclerview with mediaplayer to play a song on each row. I only have one button for play/stop which changes symbol.

    Here is my problem:

    Example 1 (This works fine):

    (For adapter position 1) the user hits the play symbol and music plays for that adapter position and the symbol changes to a stop symbol, they then hit the stop symbol and the music stops and the symbol changes back to a play symbol ready to start the music again.

    Example 2 (This is the problem)

    (For adapter position 1) the user hits the play symbol and music plays for that adapter position and the symbol changes to a stop symbol. Without hitting that button again they then hit the play symbol (adapter position 3) so now they are trying to play the song on position 1 and 3 at the same time. I have fixed both songs playing at the same time so that when the the second song is pressed the media played is reset and the source song file is changed to the new song (only one will play at a time).

    The problem then becomes even though the media player is behaving as it should. The mediaplayer is controlled in the mainactivity. The play/stop button (imageview) image is changed in the the adapter viewholder and I can't work out a way to change the play/stop symbol when more than one song is clicked at the same time.

    This image shows the example both song 1 and song 3 have been pressed. Now only song 3 is playing but the images are still showing as if both songs are playing simultaneously.

    enter image description here

    This is my view holder where I handle changing the play/stop image and send the song clicked callback:

    class AddVideoAudioViewHolder extends RecyclerView.ViewHolder{
    
        ImageView PlayButton;
        Button AddAudioButton;
        TextView Title;
        public AddVideoAudioViewHolder(View itemView) {
            super(itemView);
    
            PlayButton = (ImageView) itemView.findViewById(R.id.PlayStopAudioDemo);
            PlayButton.setTag(1);
            PlayButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    int PlayStopButtonState = (int) PlayButton.getTag();
    
                    if (PlayStopButtonState == 1) {
                        mVideoAudioCallbacks.onClick(100 + getAdapterPosition());
                        PlayButton.setImageResource(R.drawable.playstop);
                        PlayButton.setTag(2);
    
                    } else {
    
                        mVideoAudioCallbacks.onClick(200 + getAdapterPosition());
                        PlayButton.setImageResource(R.drawable.playarrow);
                        PlayButton.setTag(1);
                    }
    
    
                }
            });
    

    and this is the method in the main activity where I handle the case of two songs playing:

    public void PlaySong (int SongNumber, int ObjectInt){
    
    
        if (mp == null) {
    
            mp = new MediaPlayer();
    
        }else{
            mp.reset();
        }
    
        try {
            mp.setDataSource(this, Uri.parse("android.resource://com.example.nick.accountable/" + SongArray[SongNumber]));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            mp.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mp.start();
    
    
    
    }
    

    So my question can I add some code in the view holder or in the main activity that can change all the other views than the current adapter position. I.e. If song number 3 is clicked to play, set the image for position 1-2 & 4-10 as not playing or is there a better way to do it.

    Thanks for your help Nicholas

  • Nicholas Muir
    Nicholas Muir over 8 years
    I am not sure how to apply that. The data set hasn't changed. Are you saying I should have an array of booleans that represent the the state of the imageview button (playing/stopped)? Also is there a memory issue on doing this on button clicks?
  • Nicholas Muir
    Nicholas Muir over 8 years
    Thanks for the help.
  • Nicholas Muir
    Nicholas Muir over 8 years
    Thanks for the help.