Измените отображаемый цвет программно для каждого элемента в списке

#android #android-layout #android-recyclerview #background-color

#Android #android-макет #android-recyclerview #background-color

Вопрос:

У меня есть ресайклер с пользовательским CircleView и некоторой частью в правой части. Мне нужно изменить цвет фона правой стороны для каждого элемента программно. Каждый элемент в списке должен иметь свой собственный цвет.

введите описание изображения здесь

Код правой части элемента:

  <androidx.constraintlayout.widget.ConstraintLayout
    android:id="@ id/card_rarity_info"
    android:layout_width="0dp"
    android:layout_height="78dp"
    android:background="@drawable/shape_rarity"
    app:layout_constraintBottom_toBottomOf="@id/circle_rarity_color"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/circle_rarity_color"
    app:layout_constraintTop_toTopOf="@id/circle_rarity_color"
    tools:backgroundTint="@color/colorPrimary">

    <TextView ... />

    <TextView ... />
</androidx.constraintlayout.widget.ConstraintLayout>
  

Настройка backgroundTint в адаптере просмотра recycler:

 override fun onBindViewHolder(holder: RaritiesViewHolder, position: Int) {
    ...
    rarities[position].color?.let {
        holder.cardRarityInfo.background.setTint(Color.parseColor("#$it"))
    }
}
  

Но результат неверный! Он устанавливает последний цвет элемента для каждого элемента в списке

Ответ №1:

Просто нужно использовать mutate() для рисования.

Вот почему каждый элемент имеет одинаковый цвет:

По умолчанию все экземпляры drawables, загруженные из одного и того же ресурса, имеют общее состояние; если вы измените состояние одного экземпляра, все остальные экземпляры получат одинаковые изменения.

Когда я использую mutate() элементы для переработки в адаптере, он создает состояния для каждого отдельного элемента в списке.

Использование:

 override fun onBindViewHolder(holder: SomeViewHolder, position: Int) {
    rarities[position].color?.let {
        holder.circleView.setCircleColor(it) // custom view fun which take HEX parse it and invalidate
        holder.cardInfo.background.run {
            mutate()
            setTint(Color.parseColor("#$it"))
        }
    }
    <...>
}
  

Для получения дополнительной информации статья и документация