【问题标题】:set android:textAppearance with DataBinding使用 DataBinding 设置 android:textAppearance
【发布时间】:2016-12-22 14:58:41
【问题描述】:

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

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

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

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

【问题讨论】:

  • 介意对此问题提供反馈或接受答案,如果有适合您的解决方案?

标签: android data-binding android-databinding


【解决方案1】:

您可以使用 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>

【讨论】:

  • 谢谢,这行得通,但不知何故我不能使用它,因为用这种方法它也覆盖了typeFace,所以也不能使用自定义字体。
  • 它不起作用,因为 android:textAppearance 期望样式的 resource Id 但这里 attribute reference 正在传递。 android:textAppearance="?android:attr/textAppearanceLarge" 有效,因为 XML 解析器会为您查找所有给定的 ?attr:... 到实际的 resourceId。但是它不起作用在DataBinding表达式的情况下
【解决方案2】:

您不能直接使用它,但这是我在这种情况下使用的技巧。使用 textAppearanceLarge 和 textAppearanceMedium 作为父级创建自己的样式,然后设置这些样式:

首先创建Foo样式:

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

为FooMedium 做同样的事情。然后编辑您的布局文件,如下所示。请注意,您必须首先在 &lt;data&gt; 块中导入项目的 R 类:

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

最后应用你以前想要的外观:

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

【讨论】:

  • +1 似乎是一个不错的解决方法。但是我不能使它适用于样式属性: 预期,得到'?你能确认它不适用于风格吗?
  • 您的意思是要使用&lt;style&gt; 或设置视图样式时的条件?不过两者都行不通:(
  • 是的,我想有条件地设置视图样式。此功能存在一个问题,该功能已经使用一年了,并且没有发布到任何版本中?
【解决方案3】:

看起来 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) }
}

【讨论】:

    【解决方案4】:

    你应该使用 textStyle 而不是 textAppearance,

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

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

    For more reference use below image

    【讨论】:

    • 这不起作用,显示同样的错误&lt;expr&gt; expected, got '?'
    • android:textStyle 的用途完全不同,它只取bold|italic|normal,不涉及任何样式。
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多