当我们使用了一段时间的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:imageUrl 和android: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 并不需要规范什么名称。
这样,我们就巧妙的解决了这个字符串值的问题。
我通过以上两个开发遇到的实际问题来说这两个注解,希望大家可以看明白,如果觉得哪里说的有问题,欢迎在评论区告诉我。
分享到 Twitter
没有标签 2022-11-17 首页 • 日常 • 利用DataBinding的注解来一劳永逸 文章作者 I im CYS,一个热爱二次元的大专开发者
推荐文章
【萌新杰少】关于我的年终总结
【PHP教程】利用QR机器人获取IP地址
也许你我只认识到这是愚人节
【发现酱】以图搜图,发现你的老婆!|又一个APP!
QR机器人教程|识别图片文字