iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >Android DataBinding 基础入门(学习记录)
  • 469
分享到

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

android 2023-08-30 14:08:49 469人浏览 泡泡鱼
摘要

目录 一、DataBinding简介二、findViewById 和 DataBinding 原理及优缺点1. findViewById的优缺点2. DataBinding的优缺点 三、Android mvvm 之 data

一、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,比如初始化和数据的整体更新,如下图所示:
在这里插入图片描述
可以观察到,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 中另一个魅力所在,其行为模式如下:
在这里插入图片描述
我们可以将任何数据作为一个 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 的状态变化:
在这里插入图片描述

四、代码实例

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

android {    dataBinding {        enabled = true    }}

在布局文件中绑定指定的变量打开布局文件,选中布局文件的第一行,按住 Alt + 回车键,点击 “Convert to data binding layout”,就可以生成 DataBinding 需要的布局规则
在这里插入图片描述
在这里插入图片描述
和原始布局的区别在于多出了一个 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字符串    }}

效果:
在这里插入图片描述

来源地址:https://blog.csdn.net/weixin_74239923/article/details/132556660

--结束END--

本文标题: Android DataBinding 基础入门(学习记录)

本文链接: https://www.lsjlt.com/news/383091.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android DataBinding 基础入门(学习记录)
    目录 一、DataBinding简介二、findViewById 和 DataBinding 原理及优缺点1. findViewById的优缺点2. DataBinding的优缺点 三、Android mvvm 之 data...
    99+
    2023-08-30
    android
  • Android基础入门之dataBinding如何使用
    这篇“Android基础入门之dataBinding如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android基础...
    99+
    2023-07-02
  • Python基础学习入门
    Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。在命令行窗口输入"python" 命令来查看本地是否已经安装Python以及Python的安装版本Python下载Python官网:http://www...
    99+
    2023-06-02
  • linux 基础学习入门 3
    linux day 3第三天内容并不明确, 自我总结内部命令 用 help command   或  man bash外部命令 用 command --help 或  command -h使用手册 man command信息页 info c...
    99+
    2023-01-31
    入门 基础 linux
  • Kotlin基础学习-入门篇
    本篇文章来自郭霖大佬的第一行代码中的Kotlin教程,笔者只是在学习Kotlin过程中记录学习过程。 Kotlin系列已更新: Kotlin基础学习-入门篇 Kotlin基础学习-第二篇 Kotli...
    99+
    2023-09-07
    kotlin android
  • Android基础入门之dataBinding的简单使用教程
    目录前言1.前期准备1.1打开dataBinding1.2修改布局文件1.3修改Activity方法2.DataBinding的使用2.1属性更新2.2<data>标签2...
    99+
    2024-04-02
  • Python学习入门基础教程(lear
      在if分支判断语句里的条件判断语句不一定就是一个表达式,可以是多个(布尔)表达式的组合关系运算,这里如何使用更多的关系表达式构建出一个比较复杂的条件判断呢?这里需要再了解一下逻辑运算的基础知识。逻辑关系运算有以下几种运算符.     ...
    99+
    2023-01-31
    基础教程 入门 Python
  • Python学习入门基础教程(learn
     在Python里可以自定义函数,实现某特定功能,这里首先要区分一下函数的定义和函数的调用两个基本概念,初学者往往容易混淆。      函数的定义是指将一堆能实现特定功能的语句用一个函数名标识起来,而函数的调用则是通过函数名来使用这一堆语句...
    99+
    2023-01-31
    基础教程 入门 Python
  • JAVA MyBatis入门学习过程记录
    目录一、Mybatis1、mybatis-config.xml2、Mapper.xml3、db.properties4、MybatisUtils工具类5、多对一AND多对一:6、使用...
    99+
    2024-04-02
  • Linux 学习基础入门之Linux分区
    安装Linux,首先要有镜像文件,以CentOS为例,可以在官网或者国内某些镜像Server来获取镜像。根据自己的需要可以选择是 Everything 或者minimal iso.这里不写关于安装的细节,对于其中的一些关键步骤做些说明。1....
    99+
    2023-06-05
  • 《零基础入门学习Python》【第一版】
    测试题答案: 0. 什么是BIF?BIF 就是 Built-in Functions,内置函数。为了方便程序员快速编写脚本程序(脚本就是要编程速度快快快!!!),Python 提供了非常丰富的内置函数,我们只需要直接调用即可,例如 pri...
    99+
    2023-01-31
    入门 基础 Python
  • C#多线程学习之基础入门
    目录同步方式异步多线程方式异步多线程优化异步回调异步信号量异步多线程返回值异步多线程返回值回调线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进...
    99+
    2024-04-02
  • Python 入门学习笔记
    1 安装Anaconda和jupyter notebook   之前没有听说过这两个名词,然后看完介绍,按照我自己的理解,Anaconda是一个集合很多环境和模块的存储地方。 Jupyter notebook 就是一个可以在此环境里打代码...
    99+
    2023-01-30
    学习笔记 入门 Python
  • 【学习笔记】Mininet 入门
    【学习笔记】Mininet入门实战 课程介绍 Mininet是由一些虚拟的终端节点、交换机、路由器连接而成的一个网络仿真器,它采用轻量级的虚拟化技术使得系统可以和真实网络相媲美。 Mininet可以很方便地创建一个支持SDN的网络:...
    99+
    2023-12-22
    学习 网络 服务器
  • Ansible 入门学习笔记
    本文 的主要内容来自ansible官网书籍。 本文采用vagrant软件基于VirtualBox的虚拟机进行自动化管理,先要安装VirtualBox和vagrant两个软件。类似Docker有Dockerfile, Jenkins有Je...
    99+
    2023-01-31
    学习笔记 入门 Ansible
  • Android Qcom Audio入门学习
    总结: Android Audio不简单呀,一个人摸索入门不容易的,研究了一段时间,感觉还不是很懂,但以下的知识对入门还是有帮助的。 Audio架构中的名词 FE(Front End) 提供pcm的设备信息,将数据从用户空间传输到音频后端,...
    99+
    2023-08-24
    android audio
  • python学习笔记01-基础
    数据类型:(1)整数(2)浮点数整数和浮点数在计算机内部存储的方式是不同的(3)字符串字符\本身也要转义,所以\表示的字符就是\Python还允许用r''表示''内部的字符串默认不转义(4)布尔值在Python中,可以直接用True、F...
    99+
    2023-01-31
    学习笔记 基础 python
  • JavaScript基础学习:全面讲解,轻松入门
    JavaScript是什么? JavaScript是一种脚本语言,它与HTML和CSS一起构成了Web的三大基石。它可以用来创建交互式网页,例如动画、游戏和表单。JavaScript也是一种通用的编程语言,这意味着它可以在各种平台上运行...
    99+
    2024-02-08
    JavaScript 基础 教程 学习 入门 演示代码
  • 正则表达式基础学习一文入门
    目录正则表达式是什么元字符贪婪匹配、非贪婪匹配和独占模式分组和引用四种匹配模式断言常用正则Demo正则表达式是什么 校验数据的有效性、查找符合要求的文本以及对文本进行切割和替换等操...
    99+
    2023-03-23
    正则表达式基础 正则表达式入门
  • Python学习基础笔记(全)
    换博客了,还是csdn好一些。 Python学习基础笔记 1.Python学习—linux下Python3的安装 2.Python学习—数据类型、运算符、条件语句 3.Python学习—循环语句 4.Python学习—字符串 5.Pyt...
    99+
    2023-01-31
    基础 笔记 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作