使用Android上的数据绑定设置文本颜色

时间:2016-10-07 06:32:30

标签: android android-databinding

我尝试使用数据绑定库

设置TextView文本颜色
android:textColor="@{holder.getTitleColor(context, item)}"

Holder类中的方法定义如下

public int getTitleColor(Context context, Item item) {
   ...
}

无论我是否返回颜色int(@ColorInt)或颜色资源(@ColorRes),它都会将文本绘制为纯白色。我做错了什么?

11 个答案:

答案 0 :(得分:28)

我似乎提供的int被解释为十六进制颜色,即使这个setter应该期望资源ID看起来很直观。

使用为每个可绑定视图生成的Context引用,并使用它将资源ID转换为您指向的颜色,如described in the DataBinding Dev Guide

  

根据需要,生成一个名为context的特殊变量,用于绑定表达式。上下文的值是来自根View的getContext()的上下文。

用它来设置这样的颜色:

 <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{data.text}"
            android:textColor="@{context.getColor(data.colorRes)}"
            />

修改

为了向后兼容,您可以使用ContextCompat。需要导入:

<layout>
    <data>
        <import type="android.support.v4.content.ContextCompat"/>
        ...
    </data>
    ...
     <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{data.text}"
            android:textColor="@{ContextCompat.getColor(context, data.colorRes)}"
            />
</layout>

答案 1 :(得分:6)

使用BindingAdapter

创建方法
@BindingAdapter({"bind:color"})
public static void setFont(TextView textView, Item item) {
    textView.setTextColor(<set color of your choice>);
}

并从xml

调用它
app:color="@{item}"

答案 2 :(得分:1)

用于将部分字符串设置为颜色-与Kotlin,字符串资源和数据绑定完美配合


  • 添加绑定适配器(将其放置在所有类之外)

    @BindingAdapter("app:full_text", "app:span_text", "app:span_color")
    fun formatText(textView: TextView, full_text: String, span_text: String, span_color: Int) {
        val firstMatchingIndex = full_text.indexOf(span_text)
        val lastMatchingIndex = firstMatchingIndex + span_text.length
        val spannable = SpannableString(full_text)
        spannable.setSpan(ForegroundColorSpan(span_color), firstMatchingIndex, lastMatchingIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
        textView.text = spannable
    }
    
  • 使用变量设置字符串资源

    <string name="percentage">%1$d\%%</string>
    <string name="booking_fee">Require card and collect %1$s at Booking</string>
    
  • 将值转换为ViewHolder中的字符串(如果需要)

    fun bind(percentage: Int) {
        binding.percentage = context.resources.getString(R.string.percentage, percentage)
        binding.executePendingBindings()
    }
    
  • 通过您的xml布局应用绑定

    <data>
        <variable
            name="percentage"
            type="String" />
    </data>
    
    <TextView
        ...
        app:full_text="@{@string/booking_fee(percentage)}"
        app:span_color="@{@color/color_primary}"
        app:span_text="@{percentage}" />
    

结果:

enter image description here


请勿在布局文件中使用android:text="..."

答案 3 :(得分:0)

如下所示创建绑定适配器,这里我将所有要着色的字符串传递到{}中。在跨度中将{blah}字符串替换为彩色的blah字符串。

@BindingAdapter( "spanColor")
fun formatText(view:TextView, hexColorValue:Int) {
    val text = view.text
    val span = SpannableStringBuilder(text)
    var i = 0
    var diff = 0
    while (i < text.length) {
        val firstIndex = text.indexOf('{', i) - diff
        val secondIndex = text.indexOf('}', i) - diff
        if (firstIndex < 0 || secondIndex < 0) break
        span.delete(firstIndex, firstIndex + 1)
        span.delete(secondIndex - 1, secondIndex)
        span.setSpan(ForegroundColorSpan(hexColorValue), firstIndex, secondIndex-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        i = secondIndex + diff + 1
        diff += 2
    }
    view.text = span
}

在您的XMl文件中,将属性(app:spanColor="@{@color/colorAccent}")用作

 <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_marginTop="@dimen/space_xlarge"
                style="@style/DefaultSmallText"
                app:spanColor="@{@color/colorAccent}"
                android:text="@string/create_credential_message"/>

string.xml

<string name="create_credential_message"><![CDATA[{Username} must at least contain 8 alphanumeric characters or an email address. {Password} must be 8-20 characters long, contain uppercase, lowercase, number, & special characters.]]></string>

答案 4 :(得分:0)

要通过整数设置颜色,只需调用:

android:textColor="@{data.color}"

答案 5 :(得分:0)

除了@Mardann的解决方案之外,这是一个更新的解决方案,该解决方案也可以通过使用ContextCompat.getColor()在低于23的API上运行:

<layout>

    <data>
        <import type="androidx.core.content.ContextCompat" />
        <variable
            name="data"
            type="com.example.myapp.MyDataObject" />
    </data>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{data.text}"
        android:textColor="@{ContextCompat.getColor(context, data.colorRes)}"/>
    </layout>
  • 确保如上所述导入ContextCompat。
  • 您可以自动将“ context”作为ContextCompat.getColor()的方法参数,因为它将自动解析为视图的上下文。

答案 6 :(得分:0)

您还可以使用绑定适配器,然后使用颜色资源。

在项目中的任何地方定义此方法:

@BindingAdapter(value = "text_color") //customise your name here 
public static void setTextColor(TextView view, int color) {
    view.setTextColor(color);
}

然后在XML中使用您的新属性:

<TextView
    app:text_color="@{@color/colorPrimary}"/>

答案 7 :(得分:0)

在我的情况下,颜色值为字符串格式(例如“#000000”)

1. 字符串TxtColor =“#000000”

2. 导入“ android.graphics.Color”

<layout>
    <data>
      <import type="android.graphics.Color"/>
      <variable name="txtColor" type="String"/>
    </data>
     .... other views

</layout>

3. 设置为所需视图-在我的情况下是TextView

    ........ other views
  <android.support.v7.widget.AppCompatTextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textcolor= "@{Color.parseColor(txtColor)}" //when we import android.graphics.Color we can access it's all methods present
        tools:text="Test"/>
       ...... other views

4. 从活动/适配器绑定-在我的情况下是适配器

inner class ViewHolder(private val binding: BindingClass) :
    RecyclerView.ViewHolder(binding.root) {

    fun setData(data: DataClass, TxtColor : String?) {
        binding.txtColor= TxtColor 
        binding.executePendingBindings()
    }
}

答案 8 :(得分:0)

我的解决方案是在xml中使用此TextView声明:

<TextView
                ...
                android:textColor="@{model.getResultColor(context, index)}"
                ...
                />

以及viewModel中的此方法:

fun getResultColor(index: Int): Int {
    getItem(index)?.let { item ->
...

    return Color.GRAY
}

答案 9 :(得分:0)

object CustumBinderAdapter {
    @JvmStatic
    @BindingAdapter("text_color")
    fun setTextColor(view: TextView, color: Int) {
        when(color){
            R.color.soft_green->{
                view.setTextColor(Color.parseColor("#5abc6e"))
            }
            R.color.deep_orange->{
                view.setTextColor(Color.parseColor("#e62e30"))
            }
        }
    }

}

在XML中的用法如下:

app:text_color="@{yourViewModel.yourIntColorValue}"

答案 10 :(得分:0)

为 textview 创建一个扩展函数。

@BindingAdapter("android:colorId")
fun TextView.setTextColorValue(@ColorRes colorId: Int) {
    if (colorId == 0) return
    setTextColor(ContextCompat.getColor(context, colorId))
}

像这样在xml中使用它

<TextView
            android:id="@+id/deliveryStatus"
            android:colorId="@{model.deliveryStatusColor}" />