Android--Jetpack--Databinding详解

不经一番寒彻骨,怎得梅花扑鼻香

一,定义

DataBinding, 又名数据绑定,是Android开发中非常重要的基础技术,它可以将UI组件和数据模型连接起来,使得在数据模型发生变化时,UI组件自动更新。是 MVVM 模式在 Android 上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。MVVM 相对于 MVP,其实就是将 Presenter 层替换成了 ViewModel 层。DataBinding 能够省去我们一直以来的 findViewById() 步骤,大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout 文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常

二,基本使用

1,在app的build.gradle中 开启databinding:

defaultConfig {applicationId "com.yuanzhen.lifecycledemo"minSdk 24targetSdk 33versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"//使用databindingdataBinding{enabled true}
}

2,在布局文件XML中,选中根布局,ALT+回车:

选择Convert to data binding layout ,会自动转换为 DataBinding 需要的布局规则:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data></data><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/txt_name"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/txt_age"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_below="@+id/txt_name"/></RelativeLayout>
</layout>

3, 创建数据bean:

public class YuanZhen {public YuanZhen(String name, int age) {this.name = name;this.age = age;}private String name;private int age;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}

4,在XML中设置创建的数据bean:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data><import type="com.yuanzhen.lifecycledemo.databing.YuanZhen"/><variablename="yuanzhen"type="YuanZhen"/></data><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/txt_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{yuanzhen.name}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/txt_age"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{String.valueOf(yuanzhen.age)}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_below="@+id/txt_name"/></RelativeLayout>
</layout>

注意:这里的int需要转换为String 

5,在Activity中用DatabindingUtil 替换原来的setContentView,创建数据源,绑定databinding

public class MainActivity extends AppCompatActivity {private ActivityMainBinding dataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);YuanZhen yuanZhen =new YuanZhen("袁震",18);dataBinding.setYuanzhen(yuanZhen);}}

运行:

三,特殊用法

1,在上面我们使用的ActivityMainBinding 是自动生成的,这里我们可以自定义它的名称:MyDataBing

<data class="MyDataBing"><import type="com.yuanzhen.lifecycledemo.databing.YuanZhen"/><variablename="yuanzhen"type="YuanZhen"/>
</data>
public class MainActivity extends AppCompatActivity {private MyDataBing dataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);YuanZhen yuanZhen =new YuanZhen("袁震",18);dataBinding.setYuanzhen(yuanZhen);}
}

2,我们可以通过databinding获取在XML里面赋值的组件:

public class MainActivity extends AppCompatActivity {private MyDataBing dataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);YuanZhen yuanZhen =new YuanZhen("袁震",18);dataBinding.setYuanzhen(yuanZhen);dataBinding.txtName.setText("袁震1111");dataBinding.txtAge.setText("28");}
}

注意:这里赋值了并不会刷新

四,单向数据绑定

实现数据变化自动驱动 UI 刷新的方式有三种:BaseObservableObservableFieldObservableCollection

BaseObservable是一个纯净的 ViewModel 类被更新后,并不会让 UI 自动更新。而数据绑定后,我们自然会希望数据变更后 UI 会即时刷新,Observable 就是为此而生的概念

BaseObservable 提供了 notifyChange() 和 notifyPropertyChanged() 两个方法,前者会刷新所有的值域,后者则只更新对应 BR 的 flag,该 BR 的生成通过注释 @Bindable 生成,可以通过 BR notify 特定属性关联的视图

下面来看下使用案例:

1,将数据Bean继承BaseObservable 并实现刷新方法:

public class YuanZhen extends BaseObservable {public YuanZhen(String name, int age) {this.name = name;this.age = age;}private String name;private int age;public void setName(String name) {this.name = name;notifyPropertyChanged(BR.name);}public void setAge(int age) {this.age = age;notifyPropertyChanged(BR.age);}@Bindablepublic String getName() {return name;}@Bindablepublic int getAge() {return age;}
}

2,在Activity中每隔1s改变一下name和age:

public class MainActivity extends AppCompatActivity {private MyDataBing dataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);YuanZhen yuanZhen =new YuanZhen("袁震",18);dataBinding.setYuanzhen(yuanZhen);new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);yuanZhen.setName(yuanZhen.getName()+i);// view.setText(text);yuanZhen.setAge(18+i);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}
}

运行结果:

 五,双向数据绑定

双向绑定的意思即为当数据改变时同时使视图刷新,而视图改变时也可以同时改变数据

我们在xml里面增加一个EditText,这个EditText绑定了yuanzhen.name:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data class="MyDataBing"><import type="com.yuanzhen.lifecycledemo.databing.YuanZhen"/><variablename="yuanzhen"type="YuanZhen"/></data><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/txt_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{yuanzhen.name}"android:textSize="40sp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/txt_age"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="40sp"android:text="@{String.valueOf(yuanzhen.age)}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_below="@+id/txt_name"/><EditTextandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/txt_age"android:textSize="40sp"android:text="@={yuanzhen.name}"/></RelativeLayout>
</layout>

其余代码还是保持不变,让我们来看运行结果:

六,运算符

DataBinding 支持在布局文件中使用以下运算符、表达式和关键字*   算术 + - / \* %
*   字符串合并 +
*   逻辑 && ||
*   二元 & | ^
*   一元 + - ! ~
*   移位 >> >>> <<
*   比较 == > < >= <=
*   Instanceof
*   Grouping ()
*   character, String, numeric, null
*   Cast
*   方法调用
*   Field 访问
*   Array 访问 \[\]
*   三元 ?:目前不支持以下操作*   this
*   super
*   new
*   显示泛型调用

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux-centos上如何配置管理NFS服务器?

Linux/centos上如何配置管理NFS服务器&#xff1f; 1 NFS基础了解 NFS&#xff08;Network File System&#xff09;即文件操作系统&#xff1b;NFS允许网络中不同计算机相互之间共享资源。 1.1 NFS概述 1980年由SUN发展出来的在UNIX&Linux系统间实现文件共享的一种方法…

计算机组成原理-数据寻址-(相对寻址 基址寻址 变址寻址 )

文章目录 指令寻址vs数据寻址总览偏移寻址基址寻址基址寻址的作用变址寻址变址寻址的作用基址&变址复合寻址相对寻址相对寻址的作用 总结硬件如何实现数的比较 指令寻址vs数据寻址 总览 偏移寻址 变址寄存器&#xff1a;IX 基址寄存器&#xff1a;BR 基址寻址 没有基址…

YashanDB练习SQL

查询当前实例的信息&#xff1a; SELECT * FROM v$instance;查询数据库的信息&#xff1a; SELECT * FROM v$database;查询数据库名称&#xff1a; SELECT database_name FROM v$database;创建用户sales并授予DBA角色&#xff1a; CREATE USER sales IDENTIFIED BY "S…

【Flink on k8s】- 7 - 在本地运行第一个 flink wordcount job

目录 1、环境准备 2、代码开发 3、启动运行 4、在控制台找到 web ui,查看监控

Pair<T, U>

Pair<T, U> 表示一个包含两个元素的有序对&#xff08;pair&#xff09;。这是一种泛型类型&#xff0c;其中 T 和 U 分别表示有序对中第一个和第二个元素的类型。通常&#xff0c;Pair 类型用于表示两个相关联的值&#xff0c;例如一对坐标、一对键值等。 在 TypeScrip…

Django大回顾 - 9 Auth模块的使用、缓存

【1】Auth模块 auth就是django 的一个app&#xff0c;做用户管理。 Django作为一个完美主义者的终极框架&#xff0c;当然也会想到用户的这些痛点。它内置了强大的用户认证系统–auth&#xff0c;它默认使用 auth_user 表来存储用户数据 默认的用户表示auth_user # 创建一个用…

GitHub工业级开源软件:基于网络的过程可视化(SCADA/HMI/仪表板)

GitHub工业级开源软件:基于网络的过程可视化(SCADA/HMI/仪表板)  作者:本站编辑  2023-11-25 06:52:35  117 大家好,我是 Fun-Fun君,每天介绍github上最有价值的开源项目 今天介绍 FUXA 基于网络的过程可视化(SCADA/HMI/仪表板)软件 github地址:…

ChatGPT能帮助--掌握各种AI绘图工具,随意生成各类型性图像

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

Camunda 7.x 系列【60】流程分类

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 案例演示2.1 后端2.2 前端2.3 测试1. 前言 钉钉中的OA审批分类: 企业级的业务…

UDP多人群聊

一.创建类 二.类 1.Liao类 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String;public class Liao extends JFrame{private static final int DEFAULT_PORT8899;private JLabel st…

QT使用http通信的同步和异步

在Qt与Http通信的时候&#xff0c;会根据不同的情况使用同步或者异步的方式进行数据请求。 同步&#xff0c;即发送Http请求之后&#xff0c;会一直等待服务器返回的数据&#xff0c;接收到数据之前&#xff0c;程序一直阻塞。 异步&#xff0c;即发送Http请求之后&#xff0…

【musl-pwn】msul-pwn 刷题记录 -- musl libc 1.2.2

前言 本文不分析 musl libc 相关源码&#xff0c;仅仅为刷题记录&#xff0c;请读者自行学习相关知识&#xff08;看看源码就行了&#xff0c;代码量也不大&#xff09; starCTF2022_babynote 保护&#xff1a;保护全开 程序与漏洞分析&#xff1a; 程序实现了一个菜单堆&…

自适应局部降噪滤波器的python实现-------冈萨雷斯数字图像处理

自适应局部降噪滤波器 自适应局部降噪滤波器是一种信号处理技术&#xff0c;用于降低图像或信号中的噪声水平&#xff0c;同时保留图像或信号的细节。其原理基于局部区域内信号的统计特性和噪声的特征&#xff0c;通过动态调整滤波器的参数来适应不同区域的信号和噪声属性。 自…

Mac系统升级node.js版本和npm版本

升级node.js版本 第一步&#xff1a;查询当前node.js版本 node -v 第二步&#xff1a;清除node.js的缓存 sudo npm cache clean -f 第三步&#xff1a;验证缓存是否清空 npm cache verify 第四步&#xff1a;安装n工具&#xff0c;n工具是专门用于管理node.js版本的工具…

Day52力扣打卡

打卡记录 Collapsing Strings&#xff08;Trie树&#xff09; 链接 #include <iostream> #include <algorithm> using namespace std; const int N 2e6 10; int son[N][26], idx, cnt1[N], cnt2[N]; int main() {auto insert [&](string& str, int* c…

【Qt】在表格QTableWidget或者QTableView中,当主键Id存在时更新数据,不存在时添加数据解决方案

问题 有时在开发中&#xff0c;表格需要显示数据&#xff0c;每一行呢&#xff0c;需要记录对应的id。 当更新表格数据时&#xff0c;会根据id进行更新&#xff0c;id存在就更新行数据&#xff0c;不存在就添加一行新数据。 解决方案 如何知道id存在还是不存在呢&#xff1f…

记一次CDH集群迁移产生的问题——HIVE

背景 生产环境CDH集群迁移到新的环境&#xff0c;迁移之后使用Hive Client方执行任务一直失败。 问题1&#xff1a;metadata.SessionHiveMetaStoreClient 产生报错&#xff1a; FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.Ru…

AOP操作日志记录

AOP操作日志记录 1.创建注解 Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) public interface PassportLog {String operatePage();String operateType();ClassTypEnum classType();}2.创建切面 对于字典&#xff0c;可以通过注解属性去转换&#xff0c;枚举…

车联网架构设计(二)_消息缓存

在上一篇博客车联网架构设计(一)_消息平台的搭建-CSDN博客中&#xff0c;我介绍了车联网平台需要实现的一些功能&#xff0c;并介绍了如何用EMQXHAPROXY来搭建一个MQTT消息平台。车联网平台的应用需要消费车辆发布的消息&#xff0c;同时也会下发消息给车辆&#xff0c;以实现车…

SpringBoot 属性配置解析

属性配置介绍 spring官方提供的17中属性配置的方式 Devtools全局配置测试环境TestPropertySource注解测试环境properties属性命令行参数SPRING_APPLICATION_JSON属性ServletConfig初始化参数ServletContext初始化参数JNDI属性JAVA系统属性操作系统环境变量RandomValueProperty…