2

I have created an Adapter and ViewHolder for the recyclerView. I bind the imageButton of the itemView inside the Viewholder. And have set an onClickListener inside the onBindViewHolder.

Everything works as expected but the issue is now when i scroll down the list the selected state of the imageButton changes for the selected item and some of the items on the bottom of the list already appear selected.

Here is the some code

public class ListViewHolder extends RecyclerView.ViewHolder {
    TextView textViewUserName;
    ImageButton imageButtonCheckMark;

    public ListViewHolder(View itemView) {
        super(itemView);
        textViewUserName = (TextView) itemView.findViewById(R.id.textView_user_name);
        imageButtonCheckMark = (ImageButton) itemView.findViewById(R.id.imageButton_add_user);
    }
}

Adapter class

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {

    private LayoutInflater inflater;
    private Context context;
    private List<Metadata> list;
    public static boolean isUserSelected = false;
    ListInterface listener;

    public ListAdapter(Context context, List<Metadata> data, ListInterface listener) {
        Log.d(TAG, "Passed list to adapter : " + data.size());
        inflater = LayoutInflater.from(context);
        this.context = context;
        this.list = data;
        this.listener = listener;
    }

    @Override
    public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.item_following_people, parent, false);
        return new ListViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ListViewHolder holder, int position) {

        holder.textViewUserName.setText(list.get(position).name);

        holder.imageButtonCheckMark.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isUserSelected) {
                    holder.imageButtonCheckMark.setImageResource(R.drawable.checkmark_green);
                    isUserSelected = true;
                } else {
                    holder.imageButtonCheckMark.setImageResource(R.drawable.checkmark_grey);
                    isUserSelected = false;
                }
                listener.onUserSelected(isUserSelected, holder.getLayoutPosition());
            }
        });
    }


    @Override
    public int getItemCount() {
        return list.size();
    }
}

Inteface class

public interface ListInterface {
    public void onUserSelected(boolean userStatus, int listPosition);
}

Interface callback listener inside activity

// Interface callback listener implemented in the activity class
private ArrayList<Metadata> metadataList = new ArrayList<>();
ArrayList<String> selectedUserIdList = new ArrayList<>();

@Override
public void onUserSelected(boolean isUserSelected, int pos) {
    if (isUserSelected) {
        Log.d(TAG, "Selected user Id: " + metadataList.get(pos).userID);
        followersSelectedIdList.add(metadataList.get(pos).userID);
    } else {
        Log.d(TAG, "Removed user Id: " + metadataList.get(pos).userID);
        followersSelectedIdList.remove(metadataList.get(pos).userID);
    }
}
Gaurav Sarma
  • 2,248
  • 2
  • 24
  • 45

2 Answers2

1

Add one attribute in your model class that will save the state as your button is selected or not, write code in onBindViewHolder() to manage button view like this,

if(yourModel.getIsSelected()){
   // positive view
} else { 
   //negative view
} 
Maddy
  • 4,525
  • 4
  • 33
  • 53
0

You see this behavior because views are reused (recycled) as you scroll. You need to save the state for all buttons in the list and set the state on each button in onBindViewHolder() as it becomes visible.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • I know about the reusing of itemViews in recyclerView. Can you please share some idea on how to save the state and set the states of the button. Any article/code snippet would be really helpful. I have tried various solution in SO of making a global variable ,etc but nothing seems to work. I found 2 libraries as well but they are for more complex functionality and i don't want to add a 3rd party dependencies for this simple problem. – Gaurav Sarma Oct 20 '16 at 15:47
  • @gaurav4sarma you already gave the code to set the button state. The problem is that you only have one boolean variable for the entire list when you need one for each button. A List will do the job nicely. – Code-Apprentice Oct 20 '16 at 20:13
  • I am sorry but i am not able to implement it correctly can you please edit your answer and guide me as how to do implement it correctly ? – Gaurav Sarma Oct 22 '16 at 21:10
  • @gaurav4sarma you should post a new question showing what you tried and explaining what happens when you compile and run your code. – Code-Apprentice Oct 24 '16 at 04:19
  • @gaurav4sarma you can include that link in your new question as long as you also provide details from your own code. – Code-Apprentice Oct 24 '16 at 15:00