I\'m trying to update the items of a recycleview using notifyDataSetChanged().
This is my onBindViewHolder() method in the recycleview adapter.
@Over
You can just reset the previous listener before you make changes and you won't get this exception.
private CompoundButton.OnCheckedChangeListener checkedListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Do your stuff
});;
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(condition);
holder.checkbox.setOnCheckedChangeListener(checkedListener);
}
Using a Handler
for adding items and calling notify...()
from this Handler
fixed the issue for me.
protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView, final RecyclerView.Adapter adapter) {
handler.post(new Runnable() {
@Override
public void run() {
if (!recyclerView.isComputingLayout()) {
adapter.notifyDataSetChanged();
} else {
postAndNotifyAdapter(handler, recyclerView, adapter);
}
}
});
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.textStudentName.setText(getStudentList.get(position).getName());
holder.rbSelect.setChecked(getStudentList.get(position).isSelected());
holder.rbSelect.setTag(position); // This line is important.
holder.rbSelect.setOnClickListener(onStateChangedListener(holder.rbSelect, position));
}
@Override
public int getItemCount() {
return getStudentList.size();
}
private View.OnClickListener onStateChangedListener(final RadioButton checkBox, final int position) {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkBox.isChecked()) {
for (int i = 0; i < getStudentList.size(); i++) {
getStudentList.get(i).setSelected(false);
}
getStudentList.get(position).setSelected(checkBox.isChecked());
notifyDataSetChanged();
} else {
}
}
};
}
your CheckBox item is in changing drawable when you call notifyDataSetChanged();
so this exception would be occurred.
Try call notifyDataSetChanged();
in post of your view. For Example:
buttonView.post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
I suffered with this problem for hour and this is how you can fix it. But before you began there are some conditions to this solution.
MODEL CLASS
public class SelectUserModel {
private String userName;
private String UserId;
private Boolean isSelected;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserId() {
return UserId;
}
public void setUserId(String userId) {
UserId = userId;
}
public Boolean getSelected() {
return isSelected;
}
public void setSelected(Boolean selected) {
isSelected = selected;
}
}
CHECKBOX in ADAPTER CLASS
CheckBox cb;
ADAPTER CLASS CONSTRUCTOR & LIST OF MODEL
private List<SelectUserModel> userList;
public StudentListAdapter(List<SelectUserModel> userList) {
this.userList = userList;
for (int i = 0; i < this.userList.size(); i++) {
this.userList.get(i).setSelected(false);
}
}
ONBINDVIEW [Please use onclick in place of onCheckChange]
public void onBindViewHolder(@NonNull final StudentListAdapter.ViewHolder holder, int position) {
holder.cb.setChecked(user.getSelected());
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = (int) view.getTag();
Log.d(TAG, "onClick: " + pos);
for (int i = 0; i < userList.size(); i++) {
if (i == pos) {
userList.get(i).setSelected(true);
// an interface to listen to callbacks
clickListener.onStudentItemClicked(userList.get(i));
} else {
userList.get(i).setSelected(false);
}
}
notifyDataSetChanged();
}
});
}