Обрабатывать состояние флажка в RecyclerView, который реализует Filterable - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть 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);
    }
}
...