“终于懂了“系列:Jetpack AAC完整解析(五)DataBinding 重新认知

Jetpack AAC 系列文章:

“终于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(二)LiveData 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(四)MVVM 架构探索!

“终于懂了“系列:Jetpack AAC完整解析(五)DataBinding 架构完善!

欢迎关注我的 公 众 号,微信搜索 胡飞洋 ,文章更新可第一时间收到。

前面四篇介绍了Jetpack 架构组件中的 基础组件 以及它们的综合应用:Jetpack MVVM 架构模式,到这里已经基本满足标准化开发了。但 Jetpack 架构组件 除了 Lifecycle、LivaData、ViewModel,还有:

  • WorkManager,用于管理后台工作的任务,即使应用退出或重启时。
  • Paging,分页库,按需加载部分数据。
  • Startup,用于App启动速度优化的库,但只适用于库开发者, 郭霖这篇有详细介绍。
  • DataStore,用于替换SharedPreferences,目前还处于Alpha阶段。
  • DataBinding,将布局中的界面组件直接绑定到数据源,提供双向绑定,及高级绑定适配能力。
  • ViewBinding,用于替代findViewById,而DataBinding也包含ViewBinding的能力。
  • Room,实现本地存储 数据库管理,支持LiveData。

目前,就学习使用的必要性和库的功能性 来说,WorkManager、Paging、Startup都是非必须的,DataStore还未正式发布,ViewBinding的能力也包含在DataBinding中。Room,实际 功能和性能 同GreenDAO类似,有个好处是支持LivaData,但已使用GreenDao的项目,也不必切换为Room了。

DataBinding是比较有争议的一个库,这也是本篇的重点,相信会带你 重新认识 被误解的 DataBinding

一、重新认知 DataBinding

DataBinding的使用方法,参考官方文档就可以,介绍地很详细了,这里就不再搬运。(另外还找到一个慕课网的视频很不错:入门篇高级篇

1.1 DataBinding 的本质

应该不少人和我以前一样,对 DataBinding 的认知就是 在xml中写逻辑

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{
   !isFemale? user.name + ":男士": user.name + ":女士"}'/>

看到 xml 中 使用三元表达式 来计算view需要的值,然后就认为:“ DataBinding 不好用!在xml中写表达式逻辑,出错了debug不了啊,逻辑写在xml里面的话 xml 就承担了 Presenter/ViewModel 的职责 变得混乱了啊。”

如果是把逻辑写在xml中,确实如是:xml中是不能调试的、职责上确实是混乱了。

但,这就是 DataBinding 的本质了吗?

1.1.1 DataBinding 以前

在 DataBinding 出现以前,想要改变视图 就要引用该视图:

        TextView textView = findViewById(R.id.sample_text);
        if (textView != null && viewModel != null) {
   
            textView.setText(viewModel.getUserName());
        }

而要引用该视图就要先判空,textView 和 viewModel 都不能为空。textView为啥要判空呢?一种情况是 R.id.sample_text是定义在在其他页面中;一种情况是存在控件存在差异的 横、竖 两种布局,如横屏存在此 textView 控件,而竖屏没有,那么就需要对其做判空处理。

App内页面和控件数量繁多,一个控件可能会多处调用,这就会有出现空指针的可能,那如何完全避免呢?

1.1.2 数据绑定

DataBinding,含义是 数据绑定,即 布局中的控件可观察的数据 进行绑定。

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>

布局中这个TextView是实实在在 存在的,就不需要判空了。而user是否为空 DataBinding也会自动处理:在表达式 @{user.name} 中,如果 user 为 Null,则为 user.name 分配默认值 null。

并且,当该 user.name 被 set 新值时,被绑定了该数据的控件即可获得通知和刷新。换言之,在使用 DataBinding 后,唯一的改变是,你无需手动调用视图来 set 新状态,你只需 set 数据本身。

所以,DataBinding 并非是 将 UI 逻辑搬到 XML 中写 导致而难以调试 ,只负责绑定数据, UI 控件 与 其需要的 终态数据 进行绑定。 终态数据是指 UI 控件 直接需要的数据(UI数据),string值、int值等,而不是一段逻辑(不然就叫 LogicBinding了 ,虽然DataBinding支持逻辑表达式)。

明确了 DataBinding 的 职责边界后 应该知道了:原本的逻辑代码 该怎么写还是怎么写,只不过不再需要 textView.setText(user.name),而是直接 user.setName()。

所以 DataBinding 的本质就是 终态数据 与 UI控件 的绑定,具有以下优势

  1. 无需多处调用控件,原本调用的地方只需要set数据即可
  2. 1的延伸,无需手动判空
  3. 1的延伸,完全不用写模板代码 findViewById
  4. 并且,引入DataBinding后,原本的 UI 逻辑无需改动,只需设置终态数据

上篇提到过 Jetpack MVVM 架构本质是数据驱动,这就是说,控件的状态及数据是 被分离到 ViewModel 中管理,并且 ViewModel 这一层只需负责状态数据本身的变化,至于该数据在布局中是 被哪些视图绑定、有没有视图来绑定、以及怎么绑定,ViewModel 是不用关心的。

那控件是如何做到被通知且更新状态的呢?

DataBinding 是通过 观察者模式 来管理控件刷新状态。当状态数据变化时,只需手动地完成 setValue,这将通知 DataBinding 去刷新 该数据 绑定的控件。

而,文章开头提到的把逻辑放入xml中的写法,是不建议的。数据值应 直接反映UI控件需要的结果,而不是作为逻辑条件放在 xml 中。所以,DataBinding 不负责 UI 逻辑,逻辑原本在哪里写,现在还是在哪里写,只不过,原本调用控件实例去刷新状态的方式,现在改成了数据驱动。 这就是DataBinding 的核心目标。

1.2 例子 - 绑定列表数据

来举个例子进行说明:在页面中展示用户信息(User)列表,同时还有两个按钮用于添加、移除用户:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值