I have a RecyclerView which implements Filterable that filters the list according to user input. RecyclerView item contains a CheckBox, when selecting the checkbox without filtered result the RecyclerView retains item's checkbox state as expected but if I select a checkbox and then filter the list by searching a name the checkbox state is lost. Same issue if I select a checkbox in a filtered list but then clear the filter the state is not retained.
I have gone through various SO answers like this, but the issue is when filtering the list along with checkbox state. I have tried using a boolean in the model class as well as maintaining a HashMap for selected Ids. Still not able to resolve the issue.
This is the adapter class that I am using:
public class MultiSelectUserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private Context context;
private List<SearchItem> rowItemList;
private List<SearchItem> userListFiltered;
private HashMap<String, String> selectedIdsMap;
private LayoutInflater layoutInflater;
private MultiSelectItemViewCallback listener;
public MultiSelectUserAdapter(Context context,
List<SearchItem> rowItemList,
HashMap<String, String> selectedIdsMap,
MultiSelectItemViewCallback listener) {
this.context = context;
this.rowItemList = rowItemList;
this.userListFiltered = rowItemList;
this.selectedIdsMap = selectedIdsMap;
this.listener = listener;
}
public void updateHashMap(HashMap<String, String> selectedIds){
this.selectedIdsMap = selectedIds;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
return new NotificationsViewHolder((ItemNotificationBinding)
DataBindingUtil.inflate(layoutInflater, R.layout.item_notification,
parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
((NotificationsViewHolder) holder).bindMultiSelectItemViewHolder(context, userListFiltered.get(position),
position, selectedIdsMap, listener);
}
@Override
public int getItemCount() {
return userListFiltered.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
userListFiltered = rowItemList;
} else {
List<SearchItem> filteredList = new ArrayList<>();
for (SearchItem row : rowItemList) {
if (row.getTitle().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(row);
}
}
userListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = userListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
userListFiltered = (ArrayList<SearchItem>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
ViewHolder class:
public class NotificationsViewHolder extends RecyclerView.ViewHolder {
private final ItemNotificationBinding binding;
public NotificationsViewHolder(final ItemNotificationBinding itemBinding) {
super(itemBinding.getRoot());
this.binding = itemBinding;
}
public void bindMultiSelectItemViewHolder(Context context, final SearchItem rowItem, final int position,
HashMap<String, String> selectedIdsMap, final MultiSelectItemViewCallback callback) {
if (/*rowItem.isSelected()*/ selectedIdsMap.containsKey(rowItem.getRedirectionId())) {
binding.checkbox.setChecked(true);
}
else {
binding.checkbox.setChecked(false);
}
binding.checkbox.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setCheckClick(rowItem, position, isChecked, callback);
}
}
);
}
private void setCheckClick(SearchItem rowItem, int position, boolean isChecked,
MultiSelectItemViewCallback callback){
binding.checkbox.setChecked(isChecked);
rowItem.setSelected(isChecked);
callback.onMultiSelectItemClick(rowItem, position);
}
}
Aucun commentaire:
Enregistrer un commentaire