当前位置: 首页 > news >正文

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
*   显示泛型调用

 

相关文章:

Android--Jetpack--Databinding详解

不经一番寒彻骨&#xff0c;怎得梅花扑鼻香 一&#xff0c;定义 DataBinding, 又名数据绑定&#xff0c;是Android开发中非常重要的基础技术&#xff0c;它可以将UI组件和数据模型连接起来&#xff0c;使得在数据模型发生变化时&#xff0c;UI组件自动更新。是 MVVM 模式在 An…...

Node.js入门指南(完结)

目录 接口 介绍 RESTful json-server 接口测试工具 会话控制 介绍 cookie session token 上一篇文章我们介绍了MongoDB&#xff0c;这一篇文章是Node.js入门指南的最后一篇啦&#xff01;主要介绍接口以及会话控制。 接口 介绍 接口是前后端通信的桥梁 &#xff0…...

MySQL和Java通用加密解密方式

加密方式使用 AES 加密&#xff0c;再转成 Base64。 SQL -- 加密 update your_table set your_columnto_base64(aes_encrypt(your_column, "password"));-- 解密 select aes_decrypt(from_base64(your_column) ,"password") from your_table; 使用原生 …...

若依前端APP版使用教程

1 增加页面流程 新增Page>新增API>新增组件>新增样式>新增路径(page.json) {"path": "pages/mes/pro/feedback/index","style": {"navigationBarTitleText": "工单报工"}} <template><view class&quo…...

2023 年工程师不可错过的 AI 主要发展趋势

从对未来的好奇到关键的企业工具&#xff0c;人工智能的发展证明了它对工程师的价值。不久前&#xff0c;Gartner 预测&#xff0c;采用人工智能工程实践来构建和管理自适应人工智能系统的企业&#xff0c;在实施人工智能模型方面的表现将优于同行至少 25%&#xff0c;这为各组…...

记录 | 安装地平线工具链install_ai_toolchain.sh出现cython版本问题报错解决

安装地平线工具链 install_ai_toolchain.sh&#xff1a; cd ddk/package/host/ai_toolchain bash install_ai_toolchain.sh出现报错&#xff1a; Requirement already satisfied: packaging>20.0 in /root/.local/lib/python3.8/site-packages (from matplotlib>2.1.0-…...

Java8流操作

Java8流操作 1. 双层Map一层List 1. 双层Map一层List 代码片 // 开始分组Map<String, Map<Object, List<ProjectGeographyVO>>> collect4 vos.stream()// 注释了下行没用市级项目,只有区// .filter(data -> String.valueOf(data.getCode()).length() …...

vue-socket.io以及原生websocket的使用

vue3使用socket.io 1、安装 npm install vue-socket.io2、创建socket.js文件 export const registerSockets (sockets, proxy) > {sockets &&Object.keys(sockets).forEach((t) > {// console.log(t);// "subscribe" ! t &&// "un…...

谷歌推出功能最强大的大语言模型Gemini;大规模语言模型:从理论到实践

&#x1f989; AI新闻 &#x1f680; 谷歌推出功能最强大的大语言模型Gemini 摘要&#xff1a;谷歌正式推出其迄今为止功能最强大、最通用的大语言模型Gemini。Gemini在许多测试中表现出了最先进的性能&#xff0c;在大部分基准测试中击败了OpenAI的GPT-4。谷歌发布了三种不同…...

Android studio 工程的 module 依赖关系图绘制 、 Android Module 依赖关系的可视化实现

整体步骤&#xff1a; 1、利用gradle脚本生成dot&#xff1b; 2、利用graphviz将dot可视化转为图片 利用gradle脚本生成dot 下载projectDependencyGraph.gradle脚本 下载 projectDependencyGraph.gradle &#xff0c;放在项目根目录&#xff0c; 源码如下&#xff1a; t…...

Qt之QGraphicsView —— 笔记1.2:将QGraphicsView放置主窗口上,绘制简单图元(附完整源码)

效果 相关类介绍 QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。QGraphicsView在可滚动视口中可视化。QGraphicsView将滚动其视口,以确保该点在视图中居中。 QGraphicsScene类 提供了一个用于管理大量二维图形项的场景。请注意,QGraphicsScene没有自己的视…...

linux的权限管理

在Linux系统中&#xff0c;文件和目录的权限管理是通过用户、组以及其他用户对文件和目录的读&#xff08;r&#xff09;、写&#xff08;w&#xff09;和执行&#xff08;x&#xff09;权限来实现的。以下是有关Linux权限管理的详细解释&#xff1a; 文件和目录权限&#xff1…...

什么是 performance_schema ?

MySQL的performance_schema是运行在较低级别的用于监控MySQL Server运行过程中的资源消耗、资源等待等情况的一个功能特性&#xff0c;它具有以下特点。 performance_schema提供了一种在数据库运行时实时检查Server内部执行情况的方法。performance_schema数据库中的表使用per…...

软件多开助手的创新使用:在同一设备上玩转多个游戏

软件多开助手&#xff1a;在同一设备上玩转多个游戏的创新使用 随着科技的不断发展&#xff0c;手机和电脑已经成为我们生活中必不可少的工具。众多游戏爱好者也越来越追求在同一设备上同时体验多个游戏的乐趣。而软件多开助手的出现为这一需求提供了创新的解决方案。 传统上…...

[linux] 输出文本文件的最后一列并去重

使用 awk 命令来实现这个需求。下面是一个示例命令&#xff1a; awk -F , {print $NF} a.txt | sort -u解释一下这个命令&#xff1a; awk -F , {print $NF} a.txt&#xff1a;使用逗号作为字段分隔符&#xff08;-F ,&#xff09;&#xff0c;打印每行的最后一个字段&#x…...

新能源车交直流充电解释

交流充电&#xff1a; 国家电网输出的电都是交流电&#xff0c;如下图所示&#xff0c;具有正弦切换规律的 而电动车的电池只能接受直流电&#xff0c;因此需要首先把交流电转换成直流电才能充进汽车电池&#xff0c;这就需要到了转换器OBC&#xff08;on-board Charger&#…...

Failed to connect to gitee.com port 443: Time out 连接超时提示【Bug已完美解决-鸿蒙开发】

文章目录 项目场景:问题描述原因分析:解决方案:解决方案1解决方案2:解决方案3:此Bug解决方案总结解决方案总结**心得体会:解决连接超时问题的三种方案**项目场景: 导入Sample时遇到导入失败的情况,并提示“Failed to connect to gitee.com port 443: Time out”连接超…...

【开源】基于Vue+SpringBoot的智慧家政系统

项目编号&#xff1a; S 063 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S063&#xff0c;文末获取源码。} 项目编号&#xff1a;S063&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服…...

javaee实验:文件上传及拦截器的使用

目录 文件上传ModelAttribute注解实验目的实验内容实验过程项目结构编写代码结果展示 文件上传 Spring MVC 提供 MultipartFile 接口作为参数来处理文件上传。 MultipartFile 提供以下方法来获取上传的文件信息&#xff1a;  getOriginalFilename 获取上传的文件名字&#x…...

二分查找19(Leetcode540有序数组中的单一元素)-1

代码&#xff1a; 没用二分查找版&#xff1a; class Solution {public int singleNonDuplicate(int[] nums) {if(nums.length1){return nums[0];}for(int i1;i<nums.length-1;i){if(nums[i-1]nums[i]||nums[i]nums[i1]){continue;}else{return nums[i];}}if(nums[0]nums[…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...