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