小编典典

以编程方式更改列表中每个项目的可绘制颜色

all

我有一个带有自定义 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"))
    }
}

但结果不正确!它为列表中的每个项目设置了最后一个项目的颜色


阅读 68

收藏
2022-07-27

共1个答案

小编典典

只需要mutate()用于drawable。

这就是为什么每个项目都有相同的颜色:

默认情况下,从同一资源加载的所有可绘制实例共享一个公共状态;如果您修改一个实例的状态,所有其他实例将收到相同的修改。

当我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"))
        }
    }
    <...>
}
2022-07-27