У меня есть RecyclerView, который реализует Filterable, который фильтрует список в соответствии с пользовательским вводом. Элемент RecyclerView содержит CheckBox, при выборе флажка без отфильтрованного результата RecyclerView сохраняет состояние флажка элемента, как и ожидалось, но если я выберу флажок, а затем отфильтрую список, выполнив поиск по имени, состояние флажка будет потеряно. Та же проблема, если я устанавливаю флажок в фильтрованном списке, но затем очищаю фильтр, состояние не сохраняется.
Я прошел через различные ответы SO, такие как this , но проблема заключается в фильтрации список вместе с состоянием флажка. Я попытался использовать логическое значение в классе модели, а также поддерживать HashMap для выбранных идентификаторов. По-прежнему не удается решить проблему.
Я использую класс адаптера:
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:
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);
}
}