我有一个带有自定义 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:
override fun onBindViewHolder(holder: RaritiesViewHolder, position: Int) { ... rarities[position].color?.let { holder.cardRarityInfo.background.setTint(Color.parseColor("#$it")) } }
但结果不正确!它为列表中的每个项目设置了最后一个项目的颜色
只需要mutate()用于drawable。
mutate()
这就是为什么每个项目都有相同的颜色:
默认情况下,从同一资源加载的所有可绘制实例共享一个公共状态;如果您修改一个实例的状态,所有其他实例将收到相同的修改。
当我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")) } } <...> }