Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Image in ImageView In RecyclerView

I want to change the image of ImageView in RecyclerView.

For Example :

I have 30 items in a RecyclerView and when I click on the item at the position 1, item changes image from playing to pause, then when I scroll down to the position 15 and I click on the play button the previous selected button (item 1) should change the image back to play and the item 15 image should change to pause. I have implemented onClicklistener inside onbindViewHolder. However it is changing the image in the wrong item. Please Help me

if (mediaPlayer != null) {
    mediaPlayer.reset();
    mediaPlayer.stop();
    LinearLayout view = (LinearLayout) recyclerView.getChildAt(pos);
    ImageView button = (ImageView) view.findViewById(R.id.playbutton);
    button.setImageResource(R.drawable.ic_play_arrow_black_24dp);
}

playbutton.setOnClickListener(new View.OnClickListener() { 
    @Override
    public void onClick(View v) {
        boolean isPlaying = sharedPreferences.getBoolean(ConstantValue.ISPLAYING, false);
        RecordingDetail recordingDetail = list.get(getAdapterPosition());
        if (!isPlaying) {
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean(ConstantValue.ISPLAYING, true);
            editor.putInt(ConstantValue.CURRENTINDEX, getAdapterPosition());
            editor.commit();
            playbutton.setImageResource(R.drawable.ic_pause_black_24dp);
            mediaPlayerControl.Play(recordingDetail.path, getAdapterPosition(), progressBar);
        }
    }
}

here the play button is Image view where I want change and mediaPlayerControl is Interface

like image 687
Irfan Ullah Avatar asked Mar 06 '17 11:03

Irfan Ullah


1 Answers

You can keep track of the selected position using a global field and then check if the current view is selected inside onBindViewHolder. In addition I strongly advice you to assign the onClickListener inside your ViewHolder.

  1. Declare a global variable :

    private int selectedPosition = -1;
    
  2. Then set the selected position in your onClick and call notifyDatasetChanged :

    @Override
    public void onClick(View view) {
        selectedPosition = getAdapterPosition();    
    
        if (mediaPlayer != null) {
            mediaPlayer.reset();
            mediaPlayer.stop();
        }
    
        RecordingDetail recordingDetail = list.get(selectedPosition);            
    
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean(ConstantValue.ISPLAYING, true);
        editor.putInt(ConstantValue.CURRENTINDEX, selectedPosition);
        editor.commit();
    
        mediaPlayerControl.Play(recordingDetail.path, selectedPosition, progressBar);
    
        notifyDatasetChanged();
    }
    
  3. And finally check for the selected position in your onBindViewHodler and set the appropriate image :

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        LinearLayout view = holder.linearLayout;
        ImageView button = (ImageView) view.findViewById(R.id.playbutton);
    
        if (position == selectedPosition) {
            button.setImageResource(R.drawable.ic_pause_black_24dp);
        } else {
            button.setImageResource(R.drawable.ic_play_arrow_black_24dp);
        }
    }
    

EDIT

As @shalafi suggests, you should not keep the reference to a particlar view inside the RecyclerView adapter, bacause the views are being recycled (reused).

like image 160
Nika Kurdadze Avatar answered Nov 15 '22 01:11

Nika Kurdadze