imcys.com
遵从中二的召唤,来吧少年!

利用DataBinding的注解来一劳永逸

前言

当我们使用了一段时间的DataBinding后,我们有时可能会遇到布局传值类型不匹配的问题,或者说需要把一些复用的东西抽离出来的需求,强大的DataBinding帮我们提供了许多的注解来解决这些问题。

栗子

网络图片加载

问题

如果,我们在不使用ImageFilterView的情况下去使用ImageView,我们去给ImageView实现一个圆角,可能用卡片,或者说用Glide库,但是这样通常我们需要在任何使用它的位置添加卡片,或者写对应Glide代码。

即便ImageFilterView可以解决圆角问题,但是网络图片加载它仍然无法解决,这时,我们就想能否有一些办法,让我们给控件自定义一些属性,然后直接给这些属性写代码,通过统一的代码来完成这些属性描述的行为。

BindingAdapter

BindingAdapter,是DataBinding提供的一个注解类,我们在方法的前面加上@BindingAdapter,就可以给控件添加自定义的属性,或者修改新增原有属性的方法。

比如,我们正常情况下,给一个图片使用背景,我们会用下面这种。

android:background="@color/color_primary"

当我们给类中的方法上添加@BindingAdapter后,就重写它或者改变它传入的值的类型,并且你可以在此基础上为你的方法添加方法体,来给这个属性添加对应的逻辑。

比如,这样,我们就覆盖了安卓原来android:background接受到int值时执行的代码,我们可以在这里加一些其他的逻辑,再设置它的背景,但一般我们不会这样,后面我们会介绍到另一种注解,但是这仅仅是一个例子,告诉你格式应该是什么样的。

@BindingAdapter({"android:background"})
public static video setBackground(Button button,int color) {}

这样说,可能比较抽象,我们来看看实际例子,学习如何使用它。

解决上面的问题

首先,我们需要明确的是,我们需要通过属性配置,来使得imageview加载网络图片,并且,我们还需要有一个属性可以改变imagview的圆角。

这里,我们定义一个类,叫做ImageViewAdapter

public class ImageViewAttrAdapter {

    @BindingAdapter({"android:imageUrl", "android:imageRoundingRadius"})
    public static void loadImage(ImageView imageView, String url, int imageRoundingRadius) {

        //设置图片上去,就不在多写了
        //Glide设置图片圆角角
        RoundedCorners roundedCorners = new RoundedCorners(imageRoundingRadius);
        RequestOptions options = RequestOptions.bitmapTransform(roundedCorners);
        Glide.with(imageView.getContext())
                .load(url)
                .apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL))
                .apply(options)
                .into(imageView);

    }

    @BindingAdapter({"android:imageUrl"})
    public static void loadImage(ImageView imageView, String url) {

        //Glide设置图片圆角角度
        Glide.with(imageView.getContext())
                .load(url)
                //启用缓存数据
                .apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL))
                .into(imageView);


    }
}

从上面的类我们看见,我们在ImageViewAdapter中定义了两个静态方法,同时,我们也加入了@BindingAdapter的注解,来看看,我们其中一个类同时定义了两个属性,分别是android:imageUrlandroid:imageRoundingRadius,同时我们可以看到这个方法承接的参数,顺序是一一对应的,我们还注意到,第一个参数必须是我们需要组件的父类,比如,我们这里使用了ImageView,因此第一个参数的类型是ImageView。

后端颜色值使用问题

问题

最近,我遇到了一个问题,在加载用户页面时,后端会告诉我这个用户是不是会员,是会员的话,它的颜色值应该是什么,但是这个颜色值是16进制的字符串类型,比如#FFFFFF,因为我没办法确定这个颜色值会发生怎样的变化,因此,我只能处理这个后端的颜色值。

但是,textColor它接受的可不是字符串类型,实际上我有时候会直接用#XXXXXX,或者@color/xxxx,但它们都不是字符串类型。

如图,textColor应该接受的是color也就是int值。

但是我一开始是这样使用的。

android:textColor="@{UserCardBean.data.card.vip.status == 1 ? UserCardBean.data.card.vip.nickname_color : `#000000`}"

我利用status参数来展示用户的会员状态色,但是这样会报错,因为textColor无法接受字符串类型,这时我们就需要想个办法解决一下。

解决

相信你已经有办法来解决它了

public class TextBindingAdapter {



    @BindingAdapter(value = {"android:textColor"})
    public static void setTextColor(TextView textView, String textColor) {
        int color = Color.parseColor(textColor);
        textView.setTextColor(color);
    }


    @BindingAdapter(value = {"html"})
    public static void setTextHtml(TextView textView, String html) {
        textView.setText(Html.fromHtml(html));
    }


}

OK,这是一个办法,这样我们限制了控件,这样只能给TextView,让我们来看看另一种方法。

BindingConversion

@BindingConversion注解可以做到属性的类型转换,像是我们上面的这个问题,类型转换就很适合,因为我们不仅仅是给一个组件使用,可能很多组件都需要解决这个问题,那么我们写一次即可。

public class TextBindingAdapter {


    @BindingConversion
    public static int setTextColor(String textColor) {
        return Color.parseColor(textColor);
    }

    @BindingAdapter(value = {"html"})
    public static void setTextHtml(TextView textView, String html) {
        textView.setText(Html.fromHtml(html));
    }


}

TextBindingAdapter,我们用@BindingConversion注解了一个方法,注意,这个方法的名字得是符合你在代码里设置字体颜色的方法名称,比如这里我们使用了setTextColor,而@BindingAdapter并不需要规范什么名称。

这样,我们就巧妙的解决了这个字符串值的问题。

结尾

我通过以上两个开发遇到的实际问题来说这两个注解,希望大家可以看明白,如果觉得哪里说的有问题,欢迎在评论区告诉我。

没有标签
首页      日常      利用DataBinding的注解来一劳永逸

萌新杰少

文章作者

I im CYS,一个热爱二次元的大专开发者

发表回复

textsms
account_circle
email

Captcha Code

萌新杰少の秘密基地

利用DataBinding的注解来一劳永逸
当我们使用了一段时间的DataBinding后,我们有时可能会遇到布局传值类型不匹配的问题,或者说需要把一些复用的东西抽离出来的需求,强大的DataBinding帮我们提供了许多的注解来解决这些问题。
扫描二维码继续阅读
2022-11-17

Fatal error: Uncaught RedisException: MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error. in /www/wwwroot/User-IMCYS/www.imcys.com/wp-content/plugins/mimi-captcha/mimi-captcha.php:130 Stack trace: #0 /www/wwwroot/User-IMCYS/www.imcys.com/wp-content/plugins/mimi-captcha/mimi-captcha.php(130): session_write_close() #1 /www/wwwroot/User-IMCYS/www.imcys.com/wp-includes/class-wp-hook.php(324): micaptcha_pre_http_request() #2 /www/wwwroot/User-IMCYS/www.imcys.com/wp-includes/plugin.php(205): WP_Hook->apply_filters() #3 /www/wwwroot/User-IMCYS/www.imcys.com/wp-includes/class-wp-http.php(258): apply_filters() #4 /www/wwwroot/User-IMCYS/www.imcys.com/wp-includes/class-wp-http.php(637): WP_Http->request() #5 /www/wwwroot/User-IMCYS/www.imcys.com/wp in /www/wwwroot/User-IMCYS/www.imcys.com/wp-content/plugins/mimi-captcha/mimi-captcha.php on line 130