Can the Recyclerview viewholder change views at other positions of the adapter (not at the current position)?

I have a recyclerview with mediaplayer to play a song on every line. I have only one button for play / stop, which changes the character.

Here is my problem:

Example 1 (this works great):

(for adapter position 1), the user clicks on the play symbol, and music plays for that adapter position, and the symbol changes to a stop symbol, then they click on the stop symbol and the music stops, and the symbol returns to the play symbol, ready to start the music again.

Example 2 (This is a problem)

(for adapter position 1), the user clicks on the play symbol, and the music plays this adapter position, and the symbol changes to a stop symbol. Without pressing this button again, they then fall into the play symbol (adapter position 3), so now they are trying to play the song at positions 1 and 3 at the same time. I installed both songs at the same time, so when the second song is pressed, the media being played is reset, and the original song file is replaced with a new song (only one will play at a time).

Then a problem arises, even if the media player behaves as it should. The media layer is controlled mainly. The image of the play / stop button (image) changes in the viewport of the adapter, and I can’t develop a way to change the play / stop symbol while pressing several songs at the same time.

This image shows an example of both song 1 and song 3. Now only song 3 is played, but the images are still displayed as if both songs were playing at the same time.

enter image description here

This is my view holder, where I handle changing the play / stop image and send a callback with the song pressed:

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 action, where I handle the case of playing two songs:

 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, I can add the code to the view holder or to the main action, which can change all other views than the current adapter position. That is, if song number 3 for playback is pressed, set the image for positions 1-2 and 4-10 as not reproducing or is there a better way to do this.

Thank you for your help Nikolay

+5
source share
2 answers

Your adapter has an int variable to support which position is played.

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

in your play button on the click listener do it

 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 follow these steps

 @Override public void onBindViewHolder(AddVideoAudioViewHolder holder, int position) { if(mCurrentPlayingPosition == position ){ // display stop icon } else { // display play icon } } 
+6
source

If you want to change all other views when the action is performed on a specific line, you can call notifyDataSetChanged() and write specific if else to solve your problem in onBindViewHolder

0
source

Source: https://habr.com/ru/post/1242602/


All Articles