【问题标题】:Using attribute resources (?attr/) in layout binding?在布局绑定中使用属性资源 (?attr/)?
【发布时间】:2015-12-29 16:47:58
【问题描述】:

Android 中的数据绑定目前似乎支持以下参考资源(根据data binding guide):@array@color@int@dimen@string... 这将给出参考值作为静态 @BindingAdapter 方法中的参数。

例如:

layout/web_view.xml

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

Bindings.java

@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(WebView webView, int textColor) {
    // binding logic
}

但是对于themes and styles,我更经常使用属性资源,例如?android:attr/textColorPrimary@color 引用。对于这种情况,绑定"@{}" 语法会是什么样子?目前这就是我的工作方式,但也许有更好的方法?

layout/web_view.xml

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

Bindings.java

@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(WebView webView, int textColorAttr) {
    // binding logic
}

【问题讨论】:

    标签: android android-layout android-databinding


    【解决方案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,它就会自动完成。

    此解决方案有效,但有点过于复杂。你说数据绑定很容易..

    【讨论】:

      【解决方案2】:

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

      这里有一些设置。

      ContextUtils.java

      以下方法将提供的context 的主题attr 和可选的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;
      }
      

      我的android-commons 库(herehere)中提供了更复杂的代码。

      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
      }
      

      【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-04
        • 2020-08-11
        • 2016-09-16
        • 1970-01-01
        相关资源
        最近更新 更多