Updated 18 December 2016
Hello Everyone, this one is again very easy to implement.
The issue I faced while using check-boxes inside a Recycler View is that when I check one of the checkboxes and scroll up or down, I see many other are selected and the reason for that is that Recycler View checks the checkbox according to the current view and the holder keeps that child selected. When you log or use the selected data you will find a lot more options than selected.
For a Recycler View to work fine you need to set an Adapter and that Adapter in turns calls the ViewHolder class and you override ” onBindViewHolder ” method of the Adapter to bind the view.
When you override this method you bind all the entities of the view that are of use to you and probably set all the listeners that need to work on any of the event triggered with respect to the entities of the view inflated.
But when you do the same with the check-boxes, they don’t work exactly the same as you want them to be.
APPROACH :
All you need to do is to change the state of checkbox as per the item of the list selected and hold that value.
Don’t just change the state of the checkbox.
And for each checkbox you need to first set the OnCheckedChangeListener to null.
Look at the piece of code and you will get it :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@Override public void onBindViewHolder(final SuggestionListViewHolder holder, final int position) { final Suggestion suggestion = mSuggestionList.get(position); holder.mCheckBox.setText(suggestion.getCategory()); holder.mCheckBox.setOnCheckedChangeListener(null); holder.mCheckBox.setSelected(suggestion.isSelected()); holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ suggestion.setSelected(true); }else { suggestion.setSelected(false); } } }); holder.mCheckBox.setChecked(suggestion.isSelected()); } |
Just for a better insight , here is my full Adapter class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
public class SuggestionListAdapter extends RecyclerView.Adapter<SuggestionListAdapter.SuggestionListViewHolder> { private List<Suggestion> mSuggestionList; private Context mContext; public class SuggestionListViewHolder extends RecyclerView.ViewHolder{ private CheckBox mCheckBox; private LinearLayout mParent; public SuggestionListViewHolder(View itemView) { super(itemView); mCheckBox = (CheckBox)itemView.findViewById(R.id.list_display_checkbox); mParent =(LinearLayout)itemView.findViewById(R.id.list_parentll); } } public SuggestionListAdapter(List<Suggestion> suggestionList, Context context) { this.mSuggestionList = suggestionList; this.mContext = context; } @Override public SuggestionListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View new_suggestion_list_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.suggestion_list,parent,false); return new SuggestionListViewHolder(new_suggestion_list_view); } @Override public void onBindViewHolder(final SuggestionListViewHolder holder, final int position) { final Suggestion suggestion = mSuggestionList.get(position); holder.mCheckBox.setText(suggestion.getCategory()); holder.mCheckBox.setOnCheckedChangeListener(null); holder.mCheckBox.setSelected(suggestion.isSelected()); holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ suggestion.setSelected(true); }else { suggestion.setSelected(false); } } }); holder.mCheckBox.setChecked(suggestion.isSelected()); } @Override public int getItemCount() { return mSuggestionList.size(); } } |
Hope this works for you too.
Keep coding and keep sharing. : )
References : http://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking-different-items
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
5 comments
Well, if the Suggestion class does not have isSelected field in it.
The best solution, I would say is to create it as that’s just a boolean reference.
But Still, if you want to do it some other way or you cannot create any field in the class, then please do just share some sample code, so that I can look at the same and help you with some solution.
I just want to select only one checkbox from list.
I have dynamic checkboxes 1 2 3 4 5 6 7 but I want to select only one.
when I select a checkbox other checkboxes should remove their selection.
how can i do than
Firstly, why do you need single selected checkbox?
Have you seen RadioButton and Radio Groups? the functionality you need is already in built for RadioButtons inside a Radio Group.
Still, if you want to build the functionality using checkboxes, then you will have to set them unselected through code first.
Something like this should work :
@Override
public void onBindViewHolder(final SuggestionListViewHolder holder, final int position) {
final Suggestion suggestion = mSuggestionList.get(position);
holder.mCheckBox.setText(suggestion.getCategory());
holder.mCheckBox.setOnCheckedChangeListener(null);
holder.mCheckBox.setSelected(suggestion.isSelected());
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
for (Suggestion suggestionFromList :mSuggestionList) {
suggestionFromList.setSelected(false);
}
if(isChecked){
suggestion.setSelected(true);
}else {
suggestion.setSelected(false);
}
}
});
holder.mCheckBox.setChecked(suggestion.isSelected());
}
Thanks