在布局绑定中使用属性资源(?attr /)?

时间:2015-12-29 16:47:59

标签: android android-layout android-databinding

Android中的数据绑定目前似乎支持以下参考资源(根据data binding guide):@array@color@int@dimen,{ {1}} ...将在静态@string方法中将引用的值作为参数提供。

例如:

布局/ web_view.xml

@BindingAdapter

Bindings.java

<WebView
    app:htmlTextColor="@{@color/colorText}"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

但是对于themes and styles,我更常使用属性资源,例如@BindingAdapter({"bind:htmlTextColor"}) public static void setHtml(WebView webView, int textColor) { // binding logic } 而不是?android:attr/textColorPrimary参考。对于这种情况,绑定@color语法将如何?目前这是我如何使它工作,但也许有更好的方法?

布局/ web_view.xml

"@{}"

Bindings.java

<WebView
    app:htmlTextColor="@{android.R.attr.textColorPrimary}"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3 个答案:

答案 0 :(得分:1)

使用BindingAdapter

通过BindingAdapter,您可以在将数据应用于视图之前对其进行处理并对其进行更多的逻辑处理。要使用BindingAdapter,请先在代码中创建一个绑定到标准Android属性或自定义属性的静态方法。

我在此处创建一个名为characterBackground的自定义属性:

@BindingAdapter({"characterBackground"})
public static void characterBackground(TextView textView, AdventureTimeCharacters character) {
     textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), character.getColour()));
}

然后您可以在TextView中使用此BindingAdapter:

app:characterBackground="@{character}"

不要忘记添加应用程序名称空间! Android Studio可以为您添加。只需输入appNs,它将自动完成。

此解决方案有效,但涉及的内容过多。而且您说数据绑定很容易。

答案 1 :(得分:0)

如果@{android.R.attr.textColorPrimary}在Java中解析为android.R.attr.textColorPrimary的值,您只需要将其解析为一种颜色。

有一些设置进入此阶段。

ContextUtils.java

以下方法将attr的{​​{1}}主题和context提供的style解析为一种颜色。如果出现错误,则会回落到fallback颜色。

@ColorInt
public static int resolveColor(final Context context, @StyleRes final int style, @AttrRes final int attr, @ColorInt final int fallback) {
    final TypedArray ta = obtainTypedArray(context, style, attr);
    try {
        return ta.getColor(0, fallback);
    } finally {
        ta.recycle()
    }
}

@ColorInt
public static int resolveColor(final Context context, @AttrRes final int attr, @ColorInt final int fallback) {
    return resolveColor(context, 0, attr, fallback);
}

实用方法有助于有效实现上述目标。

private static TypedArray obtainTypedArray(final Context context, @StyleRes final int style, @AttrRes final int attr): TypedArray {
    final int[] tempArray = getTempArray();
    tempArray[0] = attr;
    return context.obtainStyledAttributes(style, tempArray);
}

private static final ThreadLocal<int[]> TEMP_ARRAY = new ThreadLocal<>();

private static final int[] getTempArray() {
    int[] tempArray = TEMP_ARRAY.get();
    if (tempArray == null) {
        tempArray = int[1];
        TEMP_ARRAY.set(tempArray);
    }
    return tempArray;
}

my android-commons library中提供了更复杂的代码(这部分用Kotlin编写,可以满足您的需求)。

Bindings.java

以下是如何使用它:

@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(final WebView webView, @AttrRes final int textColorAttr) {
    final Context context = webView.getContext();
    final int textColor = ContextUtils.resolveColor(context, textColorAttr, Color.BLACK);

    // binding logic
}

答案 2 :(得分:0)

似乎主题目前不支持在数据绑定的布局表达式中使用,如@yigit在问题here的注释中所解释的那样。