Как правильно динамически изменять цвета у элементов recyclerview
Необходима ваша помощь. Есть адаптер для RecyclerView. В него приходит объект категории с некоторым содержимым, в том числе с полем, отвечающие за важность (в нем лежит 0 или 1). В зависимости от числа, я хотел бы изменять цвет layout. Изначально реализация была в методе bind.
void bind(Category category) {
nameCategory.setText(category.nameCategory);
sumSpending.setText(String.valueOf(category.amountSpending));
if (category.importance == 1) {
nameCategoryBack.setBackgroundResource(R.drawable.back_name_necessary_category);
layoutCategoryBack.setBackgroundResource(R.color.colorSecondaryDark);
}
this.category = category;
}
Также я пробовал другую реализацию в методе onBindViewHolder().
@Override
public void onBindViewHolder(@NonNull final viewHolder holder, int position) {
holder.bind(sortedList.get(position), expenses);
if (holder.category.importance == 1) {
holder.nameCategoryBack.setBackgroundResource(R.drawable.back_name_necessary_category);
holder.layoutCategoryBack.setBackgroundResource(R.color.colorSecondaryDark);
}
}
Все идет хорошо, но после того как количество созданных элементов превысило число, после которого происходит замена содержимого элементов в RecyclerView, начинается некорректное отображение цвета layout, но содержимое остается верным. Как я могу правильно реализовать замену цветов фона layout?
Ответы (1 шт):
Как вы думаете, почему RecyclerView имеет такое название?
Вся его крутость заключается в переиспользовании элементов. RecyclerView реализует паттерн ViewHolder, суть которого заключается в том, что одновременно в памяти хранятся только те элементы которые помещаются на экране и несколько соседних.
Вместо того чтоб постоянно вызывать метод findViewById() которой выполняется не очень быстро RecyclerView переиспользует те View которые больше не видны пользователю. И у нас появляется такое понятие как DirtyView - это View на которые уже не используются но на них хранится заданные параметры какого-то элемента.
И тут появляется прикол: если вы пишите в методе onBindViewHolder() какой-то if то в момент когда эта вьюшка переиспользуется она приходит в этот if и если if не true то она просто игнорирует биндинг этого поля. Таким образом там остается старое значение.
Отсюда следует правило: "Если в методе onBindViewHolder есть if то ВСЕГДА должен быть else" в противном случае у вас будут неверные параметры от старых биндингов.
