Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

RecyclerView CheckBox

#android #checkbox #adapter #recyclerview


Знаю, что эта тема много раз поднималась для ListView, но ни как не могу разобраться
с ней на примере RecyclerView.

Есть RecyclerView, в котором повторяются CardView. RecyclerView заполняется адаптером.
Когда отмечаю несколько чек-боксов, при скроллинге вниз, некоторые чек-боксы сами становятся
отмеченными. Понял, что нужно описать этот момент в адаптере, но не нашел, где объясняется
как правильно и почему. Подскажите пожалуйста. Вот код адаптера:

public class AddFilterAdapter  extends RecyclerView.Adapter {

    private ArrayList mDataset;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public CheckBox mCheckBox;

        public ViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(R.id.tv_filter_card);
            mCheckBox = (CheckBox) v.findViewById(R.id.mcheckBox);

        }
    }

    public AddFilterAdapter(ArrayList dataset) {
        mDataset = dataset;
    }

    @Override
    public AddFilterAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                         int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.add_filter_card, parent, false);

        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.mTextView.setText(mDataset.get(position));
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }
}

    


Ответы

Ответ 1



Дело в том, что айтемы переиспользуются и для корректной работы нужно принудительно сохранять изменения в чекбоксах в отдельное хранилище, а при выводе востанавливать значения из него. Kласс RecyclerView не реализует никаких готовых методов для работы с чекбоксами, поэтому все нужно писать самому. Возможный вариант - завести отдельный массив булевых переменных и сохранять в него текущие состояния чекбоксов. На чекбоксы повешать слушатели, чтобы контролировать изменения состояний. При выводе в адаптере восстанавливать сохраненное ранее состояние. public class AddFilterAdapter extends RecyclerView.Adapter { private ArrayList mDataset; boolean[] checked; public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public CheckBox mCheckBox; public ViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.tv_filter_card); mCheckBox = (CheckBox) v.findViewById(R.id.mcheckBox); } } public AddFilterAdapter(ArrayList dataset) { mDataset = dataset; checked = new boolean[mDataset.size()]; } @Override public AddFilterAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.add_filter_card, parent, false); ViewHolder vh = new ViewHolder(v); return vh; } @Override public void onBindViewHolder(ViewHolder holder, final int position) { holder.mTextView.setText(mDataset.get(position)); holder.mCheckBox.setChecked(checked[position]); holder.mCheckBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checked[position] = !checked[position]; } }); } public boolean[] getChecked(){ return checked; @Override public int getItemCount() { return mDataset.size(); } } метод getChecked() вернет полученные значения из адаптера "наружу", например в активити, где эти данные можно обработать: // код в активити для получения чекнутых значений. boolean[] checked = filterAdapter.getChecked(); Так же вы можете не заводить отдельный массив, а создать дополнительное поле в своей модели данных и писать сохранение состояния туда, так же оттуда и восстанавливать текущее состояние для вывода. Соответственно и возвращать через геттер коллекцию самих моделей. Это может быть полезно, когда требуется связать данные самой модели и их признак чекнутости.

Комментариев нет:

Отправить комментарий