I have a cursor which retrieves a list of ingredients and populates an adapter, which is then assigned to a recycler View having checkboxes. The problem I've got is that, when I check a set of checkboxes and scroll down, the ones selected from the top, get deselected and vice versa, or in some instances, if I select three from the top, three from the bottom get selected. I need to make sure that, initially nothing is selected, and even if I scroll up and down, the ones selected should remain selected and need to keep track of.
Here is the list which is scrolable.
Here is my code:
class RecipeDetailCursorAdapter extends CursorRecyclerViewAdapter<RecyclerView.ViewHolder> {
private int mBrownColor;
private int mGreenColor;
private int mCheckItems;
private ItemsCheckedCallback mCheckedCallback;
RecipeDetailCursorAdapter(Context context, Cursor cursor, ItemsCheckedCallback callback) {
super(context, cursor);
mCheckedCallback = callback;
mBrownColor = ContextCompat.getColor(mContext, R.color.colorTextBrown);
mGreenColor = ContextCompat.getColor(mContext, R.color.colorTextGreen);
mCheckItems = 0;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, Cursor cursor) {
String taskName = cursor.getString(cursor.getColumnIndexOrThrow(MascotHelper.RecipeTask.NAME));
((RecipeTaskHolder) viewHolder).bindView(taskName);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recipe_task_item, parent, false);
return new RecipeTaskHolder(v);
}
private class RecipeTaskHolder extends RecyclerView.ViewHolder
implements SmoothCheckBox.OnCheckedChangeListener {
SmoothCheckBox taskBox;
TextView recipeComponentName;
RecipeTaskHolder(View v) {
super(v);
taskBox = (SmoothCheckBox) v.findViewById(R.id.recipe_task_box);
recipeComponentName = (TextView) v.findViewById(R.id.recipe_component_name);
taskBox.setOnCheckedChangeListener(this);
}
void bindView(String task) {
recipeComponentName.setText(task);
}
@Override
public void onCheckedChanged(SmoothCheckBox smoothCheckBox, boolean b) {
if (smoothCheckBox.isChecked()) {
recipeComponentName.setTextColor(mBrownColor);
mCheckItems++;
} else {
recipeComponentName.setTextColor(mGreenColor);
mCheckItems--;
}
if (mCheckItems == getItemCount()) {
//Toast.makeText(mContext, "All items are checked", Toast.LENGTH_SHORT).show();
mCheckedCallback.onAllItemChecked(true);
} else {
mCheckedCallback.onAllItemChecked(false);
}
}
}
interface ItemsCheckedCallback {
void onAllItemChecked(boolean status);
}
}
Any ideas or suggestions would be appreciated.
RecyclerView removes (recycles) the unseen views from the layout on scrolling, this is the basic behavior of recyclerView in order to reduce memory use.
When a view with a checkbox is recycled, a checked checkbox gets unchecked and if it has a listener, the listener gets called.
You can remove the listener from the view when it is recycled. Just override the onViewRecycled method.
@Override
public void onViewRecycled(@NonNull MyViewHolder holder) {
holder.checkBox.setOnCheckedChangeListener(null);
super.onViewRecycled(holder);
}
When the view is constructed again, while scrolling, your listener will also be added again.
use logic below on onBindView:
holder.attenCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (holder.attenCheckBox.isChecked())
dataModel.setChecked(true);
else
dataModel.setChecked(false);
}
});
if (dataModel.getChecked())
holder.attenCheckBox.setChecked(true);
else
holder.attenCheckBox.setChecked(false);
holder.checkboxLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.attenCheckBox.isChecked())
holder.attenCheckBox.setChecked(false);
else
holder.attenCheckBox.setChecked(true);
}
});
Explanation:
setOnCheckedChangeListener
will enable you to have you checked enable/disable
. Make sure you put flag after listener.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With