【问题标题】:Data Binding with theme attributes与主题属性的数据绑定
【发布时间】:2015-09-22 23:45:55
【问题描述】:

我正在试用新的 Android Databinding Library,我想使用绑定设置 ToolBar 的背景颜色。默认情况下,颜色应为 colorPrimary(来自主题)。

在我使用 DataBinding 之前,我的工具栏看起来像

 <android.support.v7.widget.Toolbar
        android:id="@+id/mainToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        />

添加绑定后,如果没有绑定颜色,我想将其背景设置为 colorPrimary - 我为此使用三元运算符(如指南中所述) - 但它会导致错误,因为主题属性也有“?”操作员在他们的名字之前。编译器认为我正在开始一个新的三元运算。

<data>
    <variable name="toolBarBackgroundColor" type="int"/>
</data>
...
<android.support.v7.widget.Toolbar
        android:id="@+id/mainToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@{toolBarBackgroundColor!=0? toolBarBackgroundColor: ?attr/colorPrimary }"
        />

那么有没有办法可以在绑定操作中访问主题属性?谢谢!

编辑

我知道我可以通过编程方式获取 colorPrimary 属性并通过 java 代码绑定它。但我只是想知道是否有基于 Xml 的解决方案。

【问题讨论】:

  • 抱歉,我们还不支持主题属性。作为一种解决方法,您可以将其定义为颜色资源值并通过 @color/colorPrimary 在三元中使用它。
  • 哦,好的。我将尝试资源价值解决方法。谢谢
  • 成功了吗?像&lt;color name="textColor"&gt;?android:attr/textColorPrimary&lt;/color&gt; 一样使用它
  • @yigit 关于支持主题属性的任何更新?
  • 不,这不太可能发生。首先,大多数视图只在其构造函数中解析这些。 View 类上没有动态的setStyle 方法。一个解决方案可能是解析应用程序样式,找出设置了哪些值,然后在视图上找到它们的设置器,但这并不可靠,因为样式从设备样式扩展而来,可以由制造商自定义。

标签: android data-binding android-theme


【解决方案1】:

寻找使用数据绑定的方法?这是我所做的测试。首先,创建一个自定义绑定适配器方法:

@BindingAdapter({"app:customPrimaryBackground"})
public static void setCustomPrimaryBackground(View v, int resId) {
    TypedValue typedValue = new TypedValue();
    Context context = v.getContext();
    if (resId == 0) {
        context.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
        v.setBackgroundResource(typedValue.resourceId);
    } else {
        // Check the given resource ID is a color or drawable
        context.getResources().getValue(resId, typedValue, true);
        Drawable drawable;
        if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
            // It's a color
            drawable = new ColorDrawable(typedValue.data);
        } else {
            drawable = ContextCompat.getDrawable(context, resId);
        }

        v.setBackground(drawable);
    }
}

二、你的绑定xml布局:

<data>
    <variable name="toolBarBackgroundColor" type="int"/>
</data>
...
<android.support.v7.widget.Toolbar
        android:id="@+id/mainToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:customPrimaryBackground="@{toolBarBackgroundColor}"
/>

【讨论】:

    【解决方案2】:

    答案有点晚,但也许对某人有帮助。

    要在数据绑定中访问主题属性,你可以这样:

    (假设clickableBoolean 变量)

    android:background="@{clickable ? android.R.attr.selectableItemBackground : android.R.color.transparent}"
    

    不需要额外的绑定适配器或其他东西。

    【讨论】:

    • 这不能正常工作。我没有完全检查就投票了。当clickable is false 似乎工作正常,但是当clickable is true 没有将selectableItemBackground 设置为背景时,因为在我的情况下它是drawable 并且在生成的代码中传递给android.databinding.adapters.Converters.convertColorToDrawable 作为color
    • 这在 2019 年也不起作用。除了不在 XML 中使用三元组之外,还有其他解决方案吗?
    • 三元表达式中的两个项需要具有相同的类型;您不能从数据绑定表达式中返回两种不同的类型(在本例中为可绘制对象和颜色)。但是,您可以使用静态方法将颜色转换为 ColorDrawable,例如导入androidx.databinding.adapters.Converters 并在三元表达式中使用Converters.convertColorToDrawable(toolBarBackgroundColor)。或者,改为使用作为 ColorDrawable 传递的值。或者,将逻辑移到数据绑定适配器方法中,这样逻辑就更容易调试了。
    【解决方案3】:

    如果问题对某人来说仍然是实际的,这是如何使用自定义和 android 属性的示例 app:textColorAttr="@{error ? com.example.R.attr.textColorError : android.R.attr.textColor}",其中 textColorAttr 使用 BindingAdapter 实现,errorBooleancom.example 是你的包名

    【讨论】:

      【解决方案4】:

      我找到了另一个没有自定义属性和绑定适配器的解决方案。这个想法是在 XML 标记中放置一个不可见的 Viewandroid:backgroundandroid:foreground 属性,并在绑定表达式中使用这些属性。

      <data>
          <variable name="toolBarBackgroundColor" type="int"/>
      </data>
      
      ...
      
      <android.support.v7.widget.Toolbar
          android:id="@+id/mainToolbar"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          android:background="@{toolBarBackgroundColor != 0 ? helperView.getBackground() : helperView.getForeground() }"
          />
      
      <View
          android:id="@+id/helperView"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:background="@{toolBarBackgroundColor}"
          android:foreground="?attr/colorPrimary"
          android:visibility="gone"
          />
      

      【讨论】:

        猜你喜欢
        • 2020-10-21
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 2017-06-03
        • 2018-09-10
        • 2010-10-10
        • 1970-01-01
        相关资源
        最近更新 更多