使用DataBinding库设置背景颜色资源或null
我想使用DataBinding库在我的视图设置背景颜色或null
,但我得到一个异常,试图运行它。
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
这是我如何做到的:
android:background="@{article.sponsored ? @color/sponsored_article_background : null}"
我也尝试设置转换,但没有奏效。
@BindingConversion public static ColorDrawable convertColorToDrawable(int color) { return new ColorDrawable(color); }
最终,我用@BindingAdapter
解决方法解决了它,但我想知道如何正确地做到这一点。
原因:
首先要知道的是,DataBinding库已经提供了位于android.databinding.adapters.Converters.convertColorToDrawable(int)
的convertColorToDrawable
绑定转换器。
使用android:background
应该“理论上”工作,因为它有一个相应的setBackground(Drawable)
方法。 问题是,它看到你尝试传递一个颜色作为第一个参数,所以它试图启动这个转换器,然后将其应用于setBackground(Drawable)
方法。 如果数据绑定决定使用一个转换器,它将在两个参数上使用它,所以在null
,就在将最终结果应用于setter之前。
由于null
不能为int
(并且不能调用intValue()
,所以它会抛出NullPointerException
异常。
官方的“ 数据绑定指南”不支持混合参数类型。
这里有两个解决这个问题的方法。 虽然您可以使用这两种解决方案中的任何一种,但第一种解决方案更容易。
解决方案:
1.可绘制
如果您不是将颜色定义为颜色,而是将其定义为资源中的drawable(可以在我们的colors.xml文件中:
<drawable name="sponsored_article_background">#your_color</drawable>
要么
<drawable name="sponsored_article_background">@color/sponsored_article_background</drawable>
那么你应该能够使用android:background
像你最初想要的,但提供drawable而不是颜色:
android:background="@{article.sponsored ? @drawable/sponsored_article_background : null}"
这里的参数具有兼容的类型:第一个是Drawable
,第二个是null,所以它也可以转换为Drawable
。
2.作为资源ID
app:backgroundResource="@{article.sponsored ? R.color.sponsored_article_background : 0}"
但它也将需要添加您的R类导入data
部分:
<data> <import type="com.example.package.R" /> <variable ... /> </data>
将0作为“空资源ID”传递是安全的,因为View
setBackgroundResource
方法检查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; }
我认为你必须尝试默认color
而不是null
喜欢这个
android:background="@{article.sponsored ? @color/sponsored_article_background : @color/your_default_color}"
你可以使用的一种方法是编写一个自定义的@BindingConversion
来为你处理:
@BindingConversion public static ColorDrawable convertColorToDrawable(int color) { return color != 0 ? new ColorDrawable(color) : null; }
有了这个,你可以将任何接受ColorDrawable
属性设置为一个整数颜色值(比如0或@android:color/transparent
),并自动将它转换为轻量级的@null。
(而内置的convertColorToDrawable(int)
转换器总是创建一个ColorDrawable
对象,即使颜色是透明的。)
注意:为了使用这个方法代替内置的@BindingConversion
,它必须返回一个ColorDrawable
而不是一个Drawable
,否则内置的方法将被视为更具体/合适。
另一种方法是在数据绑定表达式中使用静态方法将颜色转换为Drawable
,以使值类型匹配。 例如,您可以导入内置的Converters
类:
<data> <import type="android.databinding.adapters.Converters"/> </data>
…并写下你的表情:
android:background="@{article.sponsored ? Converters.convertColorToDrawable(@color/sponsored_article_background) : null}"
…虽然我个人建议将这种条件逻辑放在数据绑定适配器方法中,例如使用返回Drawable或null的getArticleBackground()
方法。 一般情况下,如果避免在布局文件中放置决策逻辑,则更易于调试和跟踪。
尝试这个:
@Bindable private int color;
和构造函数中
color = Color.parseColor("your color in String for examp.(#ffffff)")
在xml中:
android:textColor = "@{data.color}"
你可以使用@BindingAdapter(“android:background”)并设置任何资源。
如果你正在写Kotlin – 只是复制粘贴到你的项目: https : //github.com/OlegTarashkevich / ObservableBackground
- TransformException重复org / intellij / lang / annotations / Identifier.class的条目
- Jenkins DSL或Jenkins Job Builder的团队城市?
- 从Kotlin类调用方法
- 启动项目:你应该从Android还是iOS开始开发?
- 无法与Android Studio 2.3和Gradle构建项目
- Android:如何处理从左到右的滑动手势
- Kotlin的视图绑定扩展在65k方法限制之后停止工作
- 在Android Databinding中绑定ObservableList的大小
- Espresso,当NestedScrollView或RecyclerView在CoordinatorLayout中时,滚动不起作用
- 无法让dokka在gradle / android项目上生成kotlin文档
- @Rule>在Kotlin Junit测试中必须是公共的ValidationError