首页 > 解决方案 > 具有多个字符串资源的 Android 数据绑定

问题描述

我想根据事件类型在MaterialCardView 的背景中设置特定颜色(超过 3 种颜色) 。

data class Event(
    val id: Int,
    val title: String,
    val location: String,
    val type: String,
    val timeStart: String,
    val timeEnd: String,
    val creator: String,
)

object EventUtils {
    fun setCardBackgroundColor(type: String) = when (type) {
        R.string.lecture.toString() -> R.color.pistachio
        R.string.educational_practice.toString() -> R.color.yellow
        R.string.standard_practice.toString() -> R.color.azure
        R.string.lab.toString() -> R.color.lilac
        R.string.coursework.toString() -> R.color.rusty_light
        else -> R.color.colorAccent
    }
}

当我尝试使用 databinding 将接收到的事件类型传递cardBackgroundColor时,它返回的颜色值不在 setCardBackgroundColor 方法的条件列表中。

app:cardBackgroundColor="@{eventUtils.setCardBackgroundColor(event.type)}"

<?xml version="1.0" encoding="utf-8"?>
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

<data>

    <variable
        name="event"
        type="com.example.cardviewapp.model.Event" />

    <variable
        name="eventUtils"
        type="com.example.cardviewapp.ui.dashboard.EventUtils" />

    <variable
        name="viewModel"
        type="com.example.cardviewapp.ui.dashboard.DashboardViewModel" />

</data>

<com.google.android.material.card.MaterialCardView
    android:id="@+id/event_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:layout_marginHorizontal="10dp"
    android:clickable="true"
    android:focusable="true"
    app:cardCornerRadius="5dp"
    app:strokeColor="#BDBDBD"
    app:strokeWidth="1dp"
    app:cardBackgroundColor="@{eventUtils.setCardBackgroundColor(event.type)}"
    >

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">

        <TextView
            android:id="@+id/event_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:text="@{event.timeStart + '\n' + event.timeEnd}"
            android:textColor="#757575"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="08:50\n10:25" />

        <TextView
            android:id="@+id/event_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="sans-serif-black"
            android:text="@{event.title}"
            android:textColor="#000000"
            app:layout_constraintBottom_toTopOf="@+id/event_location"
            app:layout_constraintEnd_toEndOf="@+id/event_location"
            app:layout_constraintStart_toStartOf="@+id/event_location"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="spread"
            tools:text="ПТСГПОГПО" />

        <TextView
            android:id="@+id/event_location"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{event.location}"
            android:textColor="#000000"
            app:layout_constraintBottom_toTopOf="@+id/event_creator"
            app:layout_constraintEnd_toEndOf="@+id/event_creator"
            app:layout_constraintStart_toStartOf="@+id/event_creator"
            app:layout_constraintTop_toBottomOf="@+id/event_title"
            tools:text="улк 808" />

        <TextView
            android:id="@+id/event_creator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="30dp"
            android:fontFamily="monospace"
            android:text="@{event.creator}"
            android:textColor="#000000"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/event_time"
            app:layout_constraintTop_toBottomOf="@+id/event_location"
            tools:text="Аврамчук В.С." />

    </androidx.constraintlayout.widget.ConstraintLayout>


</com.google.android.material.card.MaterialCardView>

我做错了什么以及如何解决这个问题?

标签: androidandroid-recyclerviewandroid-databinding

解决方案


问题是 int 返回的 intsetCardBackgroundColor是一个资源 id,它是 int,但它需要解析,但数据绑定不这样做,而是将该 int 应用为颜色。

<com.google.android.material.card.MaterialCardView
    android:id="@+id/event_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:layout_marginHorizontal="10dp"
    android:clickable="true"
    android:focusable="true"
    app:cardCornerRadius="5dp"
    app:strokeColor="#BDBDBD"
    app:strokeWidth="1dp"
    app:cardBackgroundColor="@{eventUtils.setCardBackgroundColor(event.type,eventCard)}"
    >

注意: event_card是卡的 id,但要在调用中引用,eventCard数据绑定会为您执行此操作,event_card_abc_def将是eventCardAbcDef

然后方法会改变如下

fun setCardBackgroundColor(type: String,view:View) = 
ContextCompat.getColor(view.context,when (type) { 
        R.string.lecture.toString() -> R.color.pistachio
        R.string.educational_practice.toString() -> R.color.yellow
        R.string.standard_practice.toString() -> R.color.azure
        R.string.lab.toString() -> R.color.lilac
        R.string.coursework.toString() -> R.color.rusty_light
        else -> R.color.colorAccent
    })

推荐阅读