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个就可以确定出唯一的方法

img

从上图可以看出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);
    }
}

更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2024最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android MVVM 架构是一种基于 Model-View-ViewModel(模型-视图-视图模型)设计模式的架构,它旨在实现 Android 应用程序的高内聚、低耦合、可测试性和可维护性。在 MVVM 架构中,View(视图)和 ViewModel(视图模型)之间通过数据绑定进行通信,ViewModel(视图模型)和 Model(模型)之间通过业务逻辑进行通信。 MVVM 架构将应用程序分为三个部分: 1. Model:处理数据和业务逻辑,与数据库、网络、API 等打交道。 2. View:负责显示 UI、处理用户输入和事件,是用户与应用程序交互的界面。 3. ViewModel:作为 View 和 Model 之间的桥梁,处理视图逻辑、业务逻辑和数据绑定,将 Model 中的数据转换为 View 可以显示的数据。 在 MVVM 架构中,View 和 ViewModel 之间通过数据绑定实现双向通信,View 可以观察 ViewModel 中的数据变化,并及时更新 UI,同时用户的操作也会触发 ViewModel 中的业务逻辑,从而实现 View 和 Model 的解耦。 MVVM 架构的优点包括: 1. 高内聚、低耦合:各个模块之间的职责清晰明确,代码结构清晰,易于维护。 2. 可测试性:ViewModel 和 Model 都是纯 Java 类,不依赖 Android 系统,易于编写单元测试。 3. 可维护性:MVVM 架构使得代码易于维护和扩展,添加新功能时可以只修改 ViewModel 或 Model,而不影响 View。 总之,MVVM 架构是一种适用于 Android 应用程序的高效、可维护的架构,可以提高开发效率、代码质量和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值