使用DataBinding库设置背景颜色资源或为null [英] Use DataBinding library to set background color resource or null

查看:1328
本文介绍了使用DataBinding库设置背景颜色资源或为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用DataBinding库在视图上设置背景色或null,但是尝试运行它时出现异常.

I would like to set background color or null on my view using DataBinding library but I get an exception trying to run it.

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}"

我也尝试设置转换,但没有成功.

I also tried setting conversion but it didn't work.

@BindingConversion
public static ColorDrawable convertColorToDrawable(int color) {
   return new ColorDrawable(color);
}

最终,我使用@BindingAdapter解决了问题,但我想知道如何正确执行.

Eventually, I resolved it with workaround using @BindingAdapter but I would like to know how to do it properly.

推荐答案

原因:

首先要知道的是,DataBinding库已经提供了位于android.databinding.adapters.Converters.convertColorToDrawable(int)中的convertColorToDrawable绑定转换器.

Reason:

First thing to know is that DataBinding library already provides a convertColorToDrawable binding converter located in android.databinding.adapters.Converters.convertColorToDrawable(int).

使用android:background应该理论上"有效,因为它具有相应的

Using android:background should "theoretically" work, because it has a corresponding setBackground(Drawable) method. The problem is that it sees that you try to pass a color as a first argument so it tried to launch this converter before applying it to setBackground(Drawable) method. If databinding decides to use a converter it will use it on both arguments, so also on null, right before applying a final result to a setter.
Because null cannot be castes to int (and you cannot invoke intValue() on it) it throws NullPointerException.

提到了以下事实:官方

There is a mention about the fact that mixed argument types are not supported in official Data Binding Guide.

以下是此问题的两种解决方案.尽管您可以使用这两种解决方案中的任何一种,但第一种解决方案要容易得多.

Here are two solutions for this problem. Although you can use any of these two solutions, the first one is much easier.

1.可绘制

如果您在资源中不是将颜色定义为颜色,而是将其定义为可绘制的颜色(可以在我们的colors.xml文件中

If you define your color not as a color but as a drawable in your resources (it can be in our colors.xml file:

<drawable name="sponsored_article_background">#your_color</drawable>

<drawable name="sponsored_article_background">@color/sponsored_article_background</drawable>

然后,您应该能够像原来想要的那样使用android:background,但要提供可绘制的颜色而不是颜色:

then you should be able to use android:background like you originally wanted to but providing drawable instead of color:

android:background="@{article.sponsored ? @drawable/sponsored_article_background : null}"

此处的参数具有兼容的类型:第一个为Drawable,第二个为null,因此也可以将其强制转换为Drawable.

Here arguments has compatible types: first is Drawable and second is null so it can also be cast to a Drawable.

2.作为资源ID

app:backgroundResource="@{article.sponsored ? R.color.sponsored_article_background : 0}"

,但还需要在data部分添加您的R类导入:

but it will also require to add your R class import in data section:

<data>
    <import type="com.example.package.R" />
    <variable ... />
</data>

将0用作空资源ID"是安全的,因为ViewsetBackgroundResource方法检查resid是否不同于0,否则将null设置为背景可绘制对象.在那里没有创建不必要的透明可绘制对象.

Passing 0 as a "null resource id" is safe because setBackgroundResource method of View checks whether resid is different than 0 and sets null as a background drawable otherwise. No unnecessary transparent drawable objects are created there.

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;
}

这篇关于使用DataBinding库设置背景颜色资源或为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆