Android DataBinding 基础入门(学习记录)

这篇具有很好参考价值的文章主要介绍了Android DataBinding 基础入门(学习记录)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、DataBinding简介

DataBinding 是谷歌官方发布的一个框架,顾名思义即为数据绑定,是 MVVM 模式在 Android 上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。MVVM 相对于 MVP,其实就是将 Presenter 层替换成了 ViewModel 层。DataBinding 能够省去我们一直以来的 findViewById() 步骤,大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout 文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常

二、findViewById 和 DataBinding 原理及优缺点

1. findViewById的优缺点

findViewById的原理:Android中的View结构是一个树形结构,findViewById就是自树的根节点,依次遍历其子节点,知道找到目标的id。

  • findViewById的优点
    • 兼容性好,下面各种替代方案,都有其适用的场景,但是findViewById适用所有的场景,当你不知道用哪种方案的时候,那就用findViewById吧,肯定没有错。
    • 非常灵活,适合动态加载layout文件。比如一个Activity,需要在不同的业务中,加载两个不同的layout文件,但是两个layout文件只有部分间距不同,其他各个元素都是相同的。这个时候,用findViewId就可以完美适用。
  • findViewById的缺点
    • 性能略差不好,findViewById是基于树形结构的查找,理论上会带来性能的额外开销,但是实际项目中,因为控件的个数也不会非常非常多,所以可以忽略不计。;
    • Fragment中使用容易犯错。从原理图可以看到,在Activity中调用findViewById,实际上是调用Window中的findViewById,但是Fragment中并没有单独的Window,Fragment中调用findViewById的效果和Activity中调用的效果一模一样。所以如果一个Activity中有多个Fragment,Fragment中的控件名称又有重复的,那直接findViewById会出错的;
    • 增加代码的耦合度,findViewById随时实地都可以调用,在子view中,在Activity中等等,如果滥用起来,会让代码耦合的一塌糊涂,后面查找bug起来,非常麻烦,因为不知道View的属性在哪个类中被改变了;
    • 容易引发空指针,一个大型项目中,控件的id经常会重复,xml中删除了一个控件,但是对应的Activity中没有删除这个控件的相关引用,编译时并不会报错,但是运营室时会报出空指针;
    • 代码可读性不好,findViewById往往在Activity的onCreate方法中被引用,我们不能方便的将xml中的控件与代码中的控件结合起来,特别是如果xml的命名与代码中的命名又不规范,代码阅读起来简直就是噩梦。
2. DataBinding的优缺点

databinding会根据动态生成一个ActivityMainBinding文件,在执行ActivityMainBinding.inflate的时候,会自动生成控件的引用(mapBindings方法),这里对布局tree执行一趟遍历查找就可以生成所有的引用

  • DataBinding的优点

    • 规避了控件空指针错误,如果有引用错误,则会在编译阶段发现;
    • 效率比findViewById要高,一趟遍历可以生成所有控件的引用,而findViewById是每次执行时都需要遍历一遍
    • 代码的可读性要高,得益于Android Studio的强大功能,我们很轻易的将java(kotlin)代码中的控件引用与xml的定义结合起来
  • DataBinding的缺点

    • 灵活性不高,如果需要动态选取引用的布局文件,binding就无法适用了。
    • 改造成本较大,布局文件只有加上layout标签才可以使用。

原文链接

参考博客

三、Android mvvm 之 databinding 原理

原文

1. 简介和三个主要的实体

Data Binding 的结构[Top]
作为在 Android 开发中体现 MVVM 架构思想的 Data Binding,其核心是 观察者模式 的特定实现。首先,它有三个主要的实体:

Data

与 View 相关的数据,它可以是 View 的可观察者对象;

View

展示给用户的视图,如果有交互功能且能更新数据,它可以是 Data 的可观察者对象;

ViewDataBinding

连接 Data 和 View 的中介,当 Data 或 View 作为可观察者对象时,它充当可观察者对象的代理。假如当我们写了一个名为 demo.xml 的 Data Binding 的 layout 文件后,编译工具会生成一个相应的类——DemoBinding,它的原型就是 ViewDataBinding。我们通常通过 DataBindingUtil.inflate(inflater, R.layout.demo, container, false) 来实例化的 DemoBinding 对象,即 ViewDataBinding。

2.三个功能

其次,它主要提供了以下三个方面的功能:
将特定的 View 与特定的 Data 进行绑定,便于模块化;
View 自动感知和响应 Data 的变化,使得处理数据的业务层不必关心 View 的状态,便于解耦;
Data 也可以自动同步带有交互功能的 View 对数据的修改,使得 UI 层的交互不必担心数据是否能同步 View 状态的问题,仍然便于解耦。
基于这三个功能,Data Binding 的结构也可以划分为三个行为模式,以下一一介绍:

2.1. rebind 行为

首先,Data 往往是一个数据的集合,数据绑定的第一步就是要将整个 Data 集合绑定到 View,比如初始化和数据的整体更新,如下图所示:
Android DataBinding 基础入门(学习记录),android
可以观察到,rebind 的过程就是一个简单的赋值操作,将 View 的值设置为 Data,只不过由 ViewDataBinding 这个代理来完成这个工作。图中的 _all 参数表示将 View 的所有需要更新的节点都设置为 Data 的所有对应的成员值。当我们在 layout 文件中进行如下设置时,ViewDataBinding 将代理完成 View 中所有数据绑定节点的 data rebind 操作:

2.2 observe data 行为

有时候,我们并不需要每次更新整个 Data 集合,而只需要更新集合中的某一个成员。我们希望看到的结果是,当 Data.element_i 发生变化的时候,View.child_i 更新就可以了,而不需要将 View 的所有视图节点都重新渲染一遍。要做到这一点,我们必须要让 View 可以观察 Data 的行为。换句话说,Data 是一个可观察者对象——这是 Data Binding 中另一个魅力所在,其行为模式如下:
Android DataBinding 基础入门(学习记录),android
我们可以将任何数据作为一个 Observable,然后将 ViewDataBinding 作为 View 的代理观察者,订阅 Data 的成员变化,一旦 Data 成员变化,便通知所有观察者对象——即 ViewDataBinding,然后 ViewDataBinding 再将 View 的相应节点的值设置为 Data 相应成员的新值——即图中的 _member 参数。

这里有三个关键部分:
BaseObservable:可观察者基类(实际的祖先基类是一个 Observable 接口),实现改接口后,ViewDataBinding 就会在每次 rebind 的时候去订阅 Data 的变化;
@Bindable 标注:声明该成员是可被观察的,以及在 layout 中可以以 http://Data.xxx(标注的方法名如果为 getXXX)的方式进行访问;
notifyPropertyChanged 方法:BaseObservable 用于通知具体成员发送变化的方法,只要该方法被调用,ViewDataBinding 就会检索出是哪一个 element 的变化,并只对 View 相应的节点进行更新。

2.3 observe view 行为

在开发中,根据业务需求,我们一般能遇到两种类型的 View:
一种是只用于展示的 View,它只展示 UI 状态,而不反馈状态,我们称之为 单工View;
另一种除了展示以外,还会反馈状态给监听者,我们称之为 双工View。
在 Android 的 UI事件流中,因为所有的 View 都是可以反馈状态的,所以准确来说,所有的 View 其实都是双工的。我们在这里区分单工和双工是针对业务需求的,比如:我们很多的视图只需要它们展示就可以了,不需要监听它们的状态变化,那么我们将其归为单工View。

费尽心思进行这样的划分,是因为,单工View 只需要有 observe data 行为就可以了;而双工View 往往就需要 observe view 行为。具体来说,在反馈状态时需要更新 Data 的双工 View,我们需要进行 observe view 行为。

因为双工View 会更新 Data,所以为了保证数据的一致性,Data 需要观察双工View 的状态变化。要做到这一点,这样的双工View 必须是一个可观察者对象。得益于 UI事件流的实现,双工View天然是可观察的(只要能反馈状态,就意味着能被观察)。在自定义的双工View中,可以间接引用 ViewDataBinding,这样 ViewDataBinding 就可以代理 Data 订阅 View 的状态变化:
Android DataBinding 基础入门(学习记录),android

四、代码实例

启用 DataBinding 的方法是在对应 Model :appbuild.gradle 文件里加入以下代码,同步后就能引入对 DataBinding 的支持

android {
    dataBinding {
        enabled = true
    }
}

1、在布局文件中绑定指定的变量打开布局文件,选中布局文件的第一行,按住 Alt + 回车键,点击 “Convert to data binding layout”,就可以生成 DataBinding 需要的布局规则
Android DataBinding 基础入门(学习记录),android
Android DataBinding 基础入门(学习记录),android
和原始布局的区别在于多出了一个 layout 标签将原布局包裹了起来,data 标签用于声明要用到的变量以及变量类型,要实现 MVVM 的 ViewModel 就需要把数据(Person)与 UI(View)进行绑定,data 标签的作用就像一个桥梁搭建了 View 和 Person 之间的通道

Person类

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

在 data 标签里声明要使用到的变量名、类的全路径(如果 Person类型要多处用到,也可以直接将之 import 进来,就不用每次都指明整个包名路径)

<data>
    <variable
        name="per1"
        type="com.example.databindingpro.Person" />
    <variable
        name="work"
        type="String" />
    </data>

如果存在 import 的类名相同的情况,可以使用 alias 指定别名

    <data>
        <import type="com.leavesc.databinding_demo.model.User" />
        <import
            alias="TempUser"
            type="com.leavesc.databinding_demo.model2.User" />
        <variable
            name="userInfo"
            type="User" />
        <variable
            name="tempUserInfo"
            type="TempUser" />
    </data>

这里声明了一个 Person类型的变量per1,我们要做的就是使这个变量与两个 TextView 控件挂钩,通过设置per1的变量值同时使 TextView 显示相应的文本 完整的布局代码如下所示

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
    <variable
        name="per1"
        type="com.example.databindingpro.Person" />
    <variable
        name="work"
        type="String" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{per1.name}"
                android:textSize="30dp"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(per1.age)}"
                android:textSize="30dp"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{work}"
                android:textSize="30dp"/>
        </LinearLayout>
    </LinearLayout>
</layout>

通过 @{per1.name}使 TextView 引用到相关的变量,DataBinding 会将之映射到相应的 getter 方法 之后可以在 Activity 中通过 DataBindingUtil 设置布局文件,省略原先 Activity 的 setContentView() 方法,并为变量per1 赋值

import androidx.databinding.DataBindingUtil;
import android.app.Activity;
import android.os.Bundle;
import com.example.databindingpro.databinding.ActivityMainBinding;
public class MainActivity extends Activity {
 private ActivityMainBinding mActivityMainBinding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        mActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        com.example.databindingpro.Person person = new com.example.databindingpro.Person("张三",23);
        mActivityMainBinding.setPer1(person);//给布局文件name="per1"传入数据,类型为Person对象
        mActivityMainBinding.setWork("Teacher");//给布局文件name="work"传入数据,类型为String字符串
    }
}

效果:
Android DataBinding 基础入门(学习记录),android文章来源地址https://www.toymoban.com/news/detail-692330.html

到了这里,关于Android DataBinding 基础入门(学习记录)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android jetpack databinding的基本使用(java)

    开启databing 修改布局文件 为布局文件添加layout标签。 实例化布局文件 向布局文件传递数据 创建一个Sentence 类,实例化。传给布局并显示。 5. 在布局中引用静态类 在sentence类中添加属性collect ,collect 等于1表示已收藏,0表示收藏。 建立工具类CollectUtil 通过import导入到布局文

    2024年02月10日
    浏览(41)
  • DataBinding在Android应用中的深入解析与实战

    本文深入讲解了DataBinding在安卓应用中的作用、设置步骤、数据绑定表达式、双向绑定等关键功能,并通过实战例子展示了如何在Android项目中实现文本绑定、点击事件处理等常见场景。

    2024年02月16日
    浏览(40)
  • Kotlin开发Android之基础问题记录

    1、Kotlin中如何直接通过组件id来操作组件? 解决方案:在build.gradle中添加对相应插件的使用即可。 2、Kotlin中Button设置背景颜色没有效果。 解决方案:在res-values-themes.xml文件中修改如下代码: 3、Kotlin中如何使用静态类或者静态方法? 解决方案: 4、Kotlin中EditText的赋值问题

    2024年02月09日
    浏览(46)
  • Android 音视频入门 (四)- 记录一次MediaCodec ,天呐

    isEncoding = true //开始编码 mMediaCodec.start() //构建连接器。 mWorkerThread = HandlerThread(“WorkerThread-Encoder”) mWorkerThread.start() mHandler = Handler(mWorkerThread.looper) } 注意,我们并不在此处就开启Muxer,我们会在子线程中接受数据的时候的某个状态开始进行混合。 mCameraDevice.setPreviewCallback {

    2024年04月16日
    浏览(46)
  • Android Studio 学习记录-下拉框

    目录 下拉框控件 Spinner  数组适配器ArrayAdapter  简单适配器 SimpleAdapter         本节介绍下拉框的用法以及适配器的基本概念,结合对下拉框Spinner的使用说明分别阐述数 组适配器ArrayAdapter、简单适配器SimpleAdapter的具体用法与展示效果。         Spinner是下拉框控件,它

    2024年02月14日
    浏览(37)
  • Android Studio 学习记录-数据库

    目录 SQL的基本语法 1.数据定义语言 2.数据操纵语言 数据库管理器 SQLiteDatabase 数据库帮助器 SQLiteOpenHelper 优化记住密码功能         本文介绍Android的数据库存储方式-SQLite的使用方法,包括:SQLite用到了哪些SQL语法,如何使用数据库管理器操纵SQLite,如何使用数据库帮助器

    2024年02月07日
    浏览(53)
  • Android逆向基础入门

    一、基础App数据抓取 1、App常用抓包工具 常用的拦截抓包工具有fiddler、mitmproxy、charles ( 手机端需和电脑端在同一个网络下,且手机端要配置相应的证书,手机端还要设置手动代理 ):大部分app使用的数据通信协议基于http/https,可通过抓包查看来模拟url请求。 对于安卓手机

    2023年04月08日
    浏览(49)
  • 【Android控件】HorizontalScrollView的基础使用记录(滚动条自定义)

    目录 ​​​​​​​ 效果图 简介 注意事项 基础属性 滚动条全部设置 滚动条是否总显示 自定义滚动条滑动背景和滚动条背景 设置滚动条的宽度 设置滚动条距离 其它常规设置 设置滚动速度 布局代码示例 总结 HorizontalScrollView是水平滚动标签。垂直滚动动是 ScrollView标签 H

    2024年02月10日
    浏览(44)
  • Android Studio 学习记录-按钮控件(Button)

    目录 按钮控件(Button)         textAllCaps属性         onClick属性 点击事件和长按事件 禁用与恢复按钮         本文介绍按键控件的常见用法,包括:如何设置大小写属性,如何响应按钮的点击事件和长按事件,如何禁用按钮又该如何启用按钮,等等。        

    2023年04月22日
    浏览(49)
  • Android OpenCV基础(一、OpenCV入门)

      OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法(最基本的滤波到高级的物体检测皆有涵盖)。   OpenCV 的应用领域非常广泛,包括图像拼接、图像降噪、产品质检、人机交互、人脸识别、

    2023年04月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包