Android从零开始搭建MVVM架构(2)——Databinding之BindingAdapter

在上一篇文章《Android从零开始搭建MVVM架构(1)——Databinding入门》中,我们已经学习了Databinding的基础使用,本篇我们来学习BindingAdapter的用法,我们经常会使用自定义控件还有Android的一些控件,如RecyclerView等,当我们在这些控件的属性,就需要用到BindingAdapter,例如如下的情况:

 <com.gcssloop.widget.ArcSeekBar
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:padding="10dp"
            app:arc_colors="@array/arc_colors_custom"
            app:arc_max="100"
            app:arc_min="0"
            app:arc_open_angle="0"
            binding:arc_progress="@{viewModel.currentProgress}"
            app:arc_rotate_angle="270"
            app:arc_thumb_color="#fff"
            app:arc_thumb_mode="FILL"
            app:arc_thumb_radius="5.5dp"
            app:arc_width="4dp"
            />

这个控件中有一个自定义属性arc_progress,针对于这个属性就需要使用BindingAdapter进行绑定

为什么会有BindingAdapter

我们先来看一个布局:

 <TextView
                android:id="@+id/user_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

当我们给name设值为“Jack”的时候,DataBinding要做的事情就是:要把值为的“Jack”的字符串赋值给TextView的命名空间为android的text属性。

如果是你写DataBinding,面对上面的情况,也许会这样做:
1.忽略命名空间android
2.根据属性值text和binding表达式的值CharSequence “Jack”在TextView中寻找有如下签名的方法:
setText(CharSequence text)
3.在id为user_name的TextView上调用:setText(“Jack”)

但这样会带来什么问题?我个人思考如下:
1.不够灵活,比如text的值从未发生过改变呢,重复设置不是浪费资源?造成性能的消耗
2.如果我有特定的需求,在某些情况下才值绑定进去,这样就灵活处理
3.如果一些第三方控件,它里面设置text的方法不叫setText(CharSequence text),而是setChar(CharSequence text),那岂不是找不到方法了?

为了让我们能更加灵活的进行数据绑定,就引出了BindingAdapter

使用BindingAdapter

Android Databinding框架中已经为我们准备了大部分控件的一些属性的BindingAdapter,就比如上面的TextView:

@BindingAdapter("android:text")
    public static void setText(TextView view, CharSequence text) {
        final CharSequence oldText = view.getText();
        if (text == oldText || (text == null && oldText.length() == 0)) {
            return;
        }
        if (text instanceof Spanned) {
            if (text.equals(oldText)) {
                return; // No change in the spans, so don't set anything.
            }
        } else if (!haveContentsChanged(text, oldText)) {
            return; // No content changes, so don't set anything.
        }
        view.setText(text);
    }

将上面这个BindingAdapter注解的方法总结就是:
当在TextView上设置text属性,且设置的值的类型是CharSequence时,就不要直接调用TextView相应的setText方法,而是调用用户定义的这个BindingAdapter方法。

声明:BindingAdapter注解的方法取什么名字都行,因为压根不关心这个方法的名字,BindingAdapter只需要通过"android:text",TextView,CharSequence 这3个就可以确定出唯一的方法

在这里插入图片描述
从上图可以看出Databinding框架中已经写好了很多Android自身控件的BindingAdapter

自定义BindingAdapter

回到文章一开始提到的,如果是第三方控件,或者我们自己的自定义控件,那我们就需要自己定义BindingAdapter了,如何使用?还是拿文章一开始的自定义控件为例子

 <com.gcssloop.widget.ArcSeekBar
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:padding="10dp"
            app:arc_colors="@array/arc_colors_custom"
            app:arc_max="100"
            app:arc_min="0"
            app:arc_open_angle="0"
            binding:arc_progress="@{viewModel.currentProgress}"
            app:arc_rotate_angle="270"
            app:arc_thumb_color="#fff"
            app:arc_thumb_mode="FILL"
            app:arc_thumb_radius="5.5dp"
            app:arc_width="4dp"
            />
 <data>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="com.demo.viewmodel.TestViewModel" />
    </data>

我的自定义BindingAdapter写法如下

public final class ArcSeekBarAdapter {

    @SuppressWarnings("unchecked")
    @BindingAdapter(value = {"app:arc_progress"})
    public static void setProgress(ArcSeekBar arcSeekBar, int progress) {
        arcSeekBar.setProgress(progress);
    }
}

通过上面这些代码就可以实现自定义控件的数据绑定

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的代码家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值