原因:
首先要知道的是 DataBinding 库已经提供了一个convertColorToDrawable
位于android.databinding.adapters.Converters.convertColorToDrawable(int)
.
使用android:background
应该“理论上”有效,因为它有相应的setBackground(Drawable)
方法。问题是它看到您尝试将颜色作为第一个参数传递,因此它尝试在将其应用于setBackground(Drawable)
方法之前启动此转换器。如果数据绑定决定使用转换器,它将在两个参数上都使用它,null
在将最终结果应用于 setter 之前也是如此。
因为null
不能被种姓int
(并且你不能调用intValue()
它)它会抛出NullPointerException
.
官方数据绑定指南不支持混合参数类型。
这里有两个解决这个问题的方法。尽管您可以使用这两种解决方案中的任何一种,但第一种解决方案要容易得多。
解决方案:
1. 可绘制
如果您将颜色定义为资源中的可绘制对象而不是颜色(它可以在我们的 colors.xml 文件中:
<drawable name="sponsored_article_background">#your_color</drawable>
或者
<drawable name="sponsored_article_background">@color/sponsored_article_background</drawable>
那么你应该能够android:background
像你最初想要的那样使用,但提供可绘制而不是颜色:
android:background="@{article.sponsored ? @drawable/sponsored_article_background : null}"
这里的 arguments 具有兼容的类型: first isDrawable
和 second is null 所以它也可以转换为 a Drawable
。
2.作为资源id
app:backgroundResource="@{article.sponsored ? R.color.sponsored_article_background : 0}"
但它还需要在data
以下部分添加您的 R 类导入:
<data>
<import type="com.example.package.R" />
<variable ... />
</data>
将 0 作为“null 资源 id”传递是安全setBackgroundResource
的,因为检查方法View
是否resid
不同于 0,否则将 null 设置为背景可绘制对象。不会在那里创建不必要的透明可绘制对象。
public void setBackgroundResource(int resid) {
if (resid != 0 && resid == mBackgroundResource) {
return;
}
Drawable d= null;
if (resid != 0) {
d = mResources.getDrawable(resid);
}
setBackgroundDrawable(d);
mBackgroundResource = resid;
}