Знаю, что эта тема много раз поднималась для ListView, но ни как не могу разобраться с ней на примере RecyclerView
Есть RecyclerView, в котором повторяются CardView. RecyclerView заполняется адаптером. Когда отмечаю несколько чек-боксов, при скроллинге вниз, некоторые чек-боксы сами становятся отмеченными. Понял, что нужно описать этот момент в адаптере, но не нашел, где объясняется как правильно и почему. Подскажите пожалуйста. Вот код адаптера:
public class AddFilterAdapter extends RecyclerView.Adapter
private ArrayList
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
@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();
}
}
Ответ
Дело в том, что айтемы переиспользуются и для корректной работы нужно принудительно сохранять изменения в чекбоксах в отдельное хранилище, а при выводе востанавливать значения из него.
Kласс RecyclerView не реализует никаких готовых методов для работы с чекбоксами, поэтому все нужно писать самому.
Возможный вариант - завести отдельный массив булевых переменных и сохранять в него текущие состояния чекбоксов. На чекбоксы повешать слушатели, чтобы контролировать изменения состояний. При выводе в адаптере восстанавливать сохраненное ранее состояние.
public class AddFilterAdapter extends RecyclerView.Adapter
private ArrayList
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
@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();
Так же вы можете не заводить отдельный массив, а создать дополнительное поле в своей модели данных и писать сохранение состояния туда, так же оттуда и восстанавливать текущее состояние для вывода. Соответственно и возвращать через геттер коллекцию самих моделей. Это может быть полезно, когда требуется связать данные самой модели и их признак чекнутости.
Комментариев нет:
Отправить комментарий