使用 DataBinding 设置 android:textAppearance

set android:textAppearance with DataBinding

我正在尝试使用 DataBinding 设置 android:textAppearance ,但不允许我将 ?android:attr/textAppearanceLarge 与三元运算符一起使用。

android:textAppearance="@{position==1 ? ?android:attr/textAppearanceLarge : ?android:attr/textAppearanceMedium}"

显示编译时错误 <expr> expected, got '?'

还有其他方法可以将其与 DataBinding 一起使用吗?

您可以使用 android.R.attr 包代替 ?android:attr

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

    <data>
        <import type="android.R.attr"/>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="hello world"
            android:textAppearance='@{age==1 ? android.R.attr.textAppearanceLarge : android.R.attr.textAppearanceMedium}'
            tools:textAppearance="?android:textAppearanceLarge"
            />


    </LinearLayout>
</layout>

您应该使用 textStyle 而不是 textAppearance,

尝试使用下面给出的代码:

android:textStyle="@{position==1  ? @style/TextAppearance.Material.Large      :@style/TextAppearance.Material.Medium}"

For more reference use below image

你不能直接使用它,但是我在这种情况下使用了这个技巧。使用 textAppearanceLargetextAppearanceMedium 作为父项创建自己的样式,然后改为设置这些样式:

首先创建Foo风格:

<style name="Foo" parent="TextAppearance.AppCompat.Large">
   ... [whatever you need to set or override ] ...
</style>

并对 FooMedium 执行相同的操作。然后编辑您的布局文件,如下所示。请注意,您必须首先在 <data> 块中导入项目的 R class:

<data>
   <import type="<your-package-id>.R"
</data>

最终应用您之前想要的外观:

android:textAppearance="@{ position==1 ? R.style.Foo : R.style.FooMedium }"

看起来 DataBinding 以某种特殊方式处理 android:textAppearance(至少在 Android Studio 3.2.1 上)。

例如,根据 this 的以下表达式应该没问题,但 它不是

编译器正在接受以下表达式,但它什么也不做:

android:textAppearance="@{R.style.MyStyleTest}"

我尝试了几种选择,但只有香草方式适合我:

android:textAppearance="@style/MyStyleTest"

作为解决方案

我建议使用 @BindingAdapter 并在那里执行所有逻辑。

例如,如果您想使用对属性的引用(看起来像:?attr/...),请使用以下方法:

layout.xml

<TextView 
    ...
    bind:textAppearanceAttr="@{position==1 ? android.R.attr.textAppearanceLarge: android.R.attr.textAppearanceMedium}" 
/>

sources.kt

@BindingAdapter(value = ["textAppearanceAttr"])
fun textAppearanceAttr(textView: TextView, @AttrRes attrRef: Int?) {
    attrRef?.also {
        val attrs = textView.context.obtainStyledAttributes(intArrayOf(attrRef))
        val styleRes = attrs.getResourceId(0, -1)
        attrs.recycle()
        if (styleRes != -1) {
            TextViewCompat.setTextAppearance(textView, styleRes)
        }
    }
}

或者样式资源 ID (@style/...):

layout.xml

bind:textAppearanceStyle="@{position==1 ? R.style.MyStyleTest1: R.style.MyStyleTest2}"

sources.kt

@BindingAdapter(value = ["textAppearanceStyle"])
fun textAppearanceStyle(textView: TextView, @StyleRes style: Int?) {
    style?.also { TextViewCompat.setTextAppearance(textView, it) }
}