深入解析 androidx.databinding.BaseObservable

在现代 Android 开发中,数据绑定 (Data Binding) 是一个重要的技术,它简化了 UI 和数据之间的交互。在数据绑定框架中,androidx.databinding.BaseObservable 是一个关键类,用于实现可观察的数据模型。本文将详细介绍 BaseObservable 的用法和原理,帮助你更好地掌握数据绑定技术。
什么是 BaseObservable?
BaseObservable 是一个基础类,它实现了 Observable 接口,使得数据模型能够被观察。当数据模型中的属性发生变化时,BaseObservable 可以通知所有的观察者(通常是绑定的 UI 视图)自动更新。
基本用法
创建一个继承自 BaseObservable 的类
要使用 BaseObservable,我们需要创建一个继承自 BaseObservable 的类,并在需要通知变化的属性上添加 @Bindable 注解。然后,在属性的 setter 方法中调用 notifyPropertyChanged 方法。
下面是一个简单的示例,展示如何创建一个用户类,并使用 BaseObservable 和 @Bindable 实现数据绑定:
import androidx.databinding.BaseObservable
import androidx.databinding.Bindableclass User : BaseObservable() {var firstName: String = ""@Bindable get() = fieldset(value) {field = valuenotifyPropertyChanged(BR.firstName)}var lastName: String = ""@Bindable get() = fieldset(value) {field = valuenotifyPropertyChanged(BR.lastName)}
}
在这个示例中,User 类继承自 BaseObservable,并且使用 @Bindable 注解标记了 firstName 和 lastName 属性。当这些属性的值发生变化时,notifyPropertyChanged 方法会通知数据绑定框架更新 UI。
在布局文件中使用数据绑定
接下来,我们需要在布局文件中使用数据绑定。首先,在项目的 build.gradle 文件中启用数据绑定:
android {...dataBinding {enabled = true}
}
然后,在布局文件中使用数据绑定。在根布局中添加 layout 标签,并声明一个 User 类型的变量:
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="user"type="com.example.app.User" /></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@={user.firstName}" /><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@={user.lastName}" /></LinearLayout>
</layout>
在 Activity 或 Fragment 中绑定数据
最后,在 Activity 或 Fragment 中绑定数据并设置视图模型:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.app.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)val user = User().apply {firstName = "John"lastName = "Doe"}binding.user = user}
}
深入理解 BaseObservable 的工作原理
BaseObservable 的核心在于它实现了 Observable 接口,并且提供了一组方法,用于管理观察者和通知属性变化。
notifyPropertyChanged 方法
notifyPropertyChanged 方法用于通知数据绑定框架某个属性的值发生了变化。我们需要在属性的 setter 方法中调用它,并传递相应的属性 ID。例如:
var firstName: String = ""@Bindable get() = fieldset(value) {field = valuenotifyPropertyChanged(BR.firstName)}
notifyChange 方法
如果多个属性的值发生了变化,或者我们想要一次性通知所有的绑定属性发生了变化,可以使用 notifyChange 方法:
fun updateUser(firstName: String, lastName: String) {this.firstName = firstNamethis.lastName = lastNamenotifyChange()
}
自动生成的 BR 类
当我们在属性上添加 @Bindable 注解时,数据绑定框架会自动生成一个 BR 类。这个类包含了所有绑定属性的 ID,用于在属性值变化时通知数据绑定框架。例如,BR.firstName 和 BR.lastName 就是自动生成的 ID。
object BR {@JvmFieldval _all = 0@JvmFieldval firstName = 1@JvmFieldval lastName = 2
}
高级用法
双向数据绑定
双向数据绑定允许我们在视图和数据模型之间实现双向同步。例如,当用户在 EditText 中输入文本时,数据模型会自动更新;同样,当数据模型的值发生变化时,视图也会自动更新。我们可以通过在 XML 中使用 @= 语法来实现双向数据绑定:
<EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@={user.firstName}" />
自定义属性和 BindingAdapter
有时候,我们需要在视图上绑定一些自定义属性。为此,我们可以使用 BindingAdapter 注解来自定义数据绑定逻辑。例如,我们可以为 ImageView 创建一个自定义绑定适配器,用于加载网络图片:
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glideobject BindingAdapters {@JvmStatic@BindingAdapter("imageUrl")fun loadImage(view: ImageView, url: String?) {if (!url.isNullOrEmpty()) {Glide.with(view.context).load(url).into(view)}}
}
在布局文件中使用自定义属性:
<ImageViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:imageUrl="@{viewModel.imageUrl}" />
性能优化
在使用数据绑定时,我们需要注意性能优化,特别是在大型项目中。以下是一些常见的优化建议:
使用 ObservableField
对于简单的单个字段绑定,可以使用 ObservableField 来代替 @Bindable 注解和 BaseObservable,这样可以减少代码量并提高性能:
import androidx.databinding.ObservableFieldclass User {val firstName = ObservableField<String>()val lastName = ObservableField<String>()
}
避免过度绑定
绑定的数据越多,数据绑定框架的开销就越大。尽量只绑定必要的数据,避免不必要的绑定和数据刷新。
结论
BaseObservable 是 Android 数据绑定框架中的一个重要组件,通过它可以实现数据和视图的双向绑定,从而简化代码结构,提高代码的可维护性。通过本文的介绍,相信你已经对 BaseObservable 的基本用法、高级用法和性能优化有了更深入的了解。在实际开发中,合理使用 BaseObservable 和数据绑定框架,可以大大提升开发效率和应用的用户体验。
Best regards!
相关文章:
深入解析 androidx.databinding.BaseObservable
在现代 Android 开发中,数据绑定 (Data Binding) 是一个重要的技术,它简化了 UI 和数据之间的交互。在数据绑定框架中,androidx.databinding.BaseObservable 是一个关键类,用于实现可观察的数据模型。本文将详细介绍 BaseObservab…...
MySQL数据恢复(适用于误删后马上发现)
首先解释一下标题,之所以适用于误删后马上发现是因为太久了之后时间和当时操作的数据表可能会记不清楚,不是因为日志丢失 1.首先确保自己的数据库开启了binlog(我的是默认开启的我没有配置过) 根据这篇博客查看自己的配置和自己…...
[数据结构】——七种常见排序
文章目录 前言 一.冒泡排序二.选择排序三.插入排序四.希尔排序五.堆排序六.快速排序hoare挖坑法前后指针快排递归实现:快排非递归实现: 七、归并排序归并递归实现:归并非递归实现: 八、各个排序的对比图 前言 排序:所谓…...
CPU占用率飙升至100%:是攻击还是正常现象?
在运维和开发的日常工作中,CPU占用率突然飙升至100%往往是一个令人紧张的信号。这可能意味着服务器正在遭受攻击,但也可能是由于某些正常的、但资源密集型的任务或进程造成的。本文将探讨如何识别和应对服务器的异常CPU占用情况,并通过Python…...
java如何替换字符串中给定索引的字符
java如果要修改给定字符串的索引字符,需要用到setCharAt方法 它的语法格式是 sbf.setCharAt(index,ch) 其中: sbf是任意StringBuffer对象 index是被替换字符的索引 ch是替换后的索引 如果是修改一个字符就用这个方法。如果是批量修改,…...
基于RK3588的GMSL、FPDLink 、VByone及MIPI等多种摄像模组,适用于车载、机器人工业图像识别领域
机器人&工业摄像头 针对机器人视觉与工业检测视觉,信迈自主研发和生产GMSL、FPDLink 、VByone及MIPI等多种摄像模组,并为不同应用场景提供多种视场角度和镜头。拥有资深的图像算法和图像ISP专家团队,能够在软件驱动层开发、ISP算法、FPG…...
Windows 的 MFC开发的使用示例——讲得挺好的
【Visual Studio 2019】创建 MFC 桌面程序 ( 安装 MFC 开发组件 | 创建 MFC 应用 | MFC 应用窗口编辑 | 为按钮添加点击事件 | 修改按钮文字 | 打开应用 )-腾讯云开发者社区-腾讯云 (tencent.com)...
Spring4.3.x xml配置文件搜索和解析过程
###概述 这篇文章的研究不只是涉及到spring如何创建一个BeanDefinition对象,还涉及到spring如何加载文件、如何读取XML文件、以及我们在使用spring的时候如何扩展spring的配置。 spring在创建BeanFactory时会把xml配置文件和注解信息转换为一个个BeanDefinition对…...
网络爬虫(一)深度优先爬虫与广度优先爬虫
1. 深度优先爬虫:深度优先爬虫是一种以深度为优先的爬虫算法。它从一个起始点开始,先访问一个链接,然后再访问该链接下的链接,一直深入地访问直到无法再继续深入为止。然后回溯到上一个链接,再继续深入访问下一个未被访…...
JavaScript懒加载图像
懒加载图像是一种优化网页性能的技术,它将页面中的图像延迟加载,即在用户需要查看它们之前不会立即加载。这种技术通常用于处理大量或大尺寸图像的网页,特别是那些包含长页面或大量媒体内容的网站。 好处 **1. 加快页面加载速度:…...
Git指令
一 参考:https://zhuanlan.zhihu.com/p/389814854 1.clone远程仓库 git clone https://git.xiaojukeji.com/falcon-mg/dagger.git 2.增加当前子目录下所有更改过的文件至index git add . 3.提交并备注‘xxx’ git commit -m ‘xxx’ 4.显示本地分支 git branch 5.显…...
DllImport进阶:参数配置与高级主题探究
深入讨论DllImport属性的作用和配置方法 在基础篇中,我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…...
HTTP与HTTPS协议区别及应用场景
HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)都是用于通过网络传输数据的协议。虽然它们有一些相似之处,但在安全性和数据保护方面也存在显著差异。 在这篇博文中,我们将探讨 HTTP 和 HTTPS…...
Vue2-Vue Router前端路由实现思路
1.路由是什么? Router路由器:数据包转发设备,路由器通过转发数据包(数据分组)来实现网络互连 Route路由:数据分组从源到目的地时,决定端到端路径的网络范围的进程 | - 网络层 Distribute分发…...
2024 年 亚太赛 APMCM (C题)中文赛道国际大学生数学建模挑战赛 | 量子计算的物流配送 | 数学建模完整代码+建模过程全解全析
当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题! 完整内容可以在文章末尾领取! 该段文字…...
客观分析-自己和本科学生之间的差距
进入专科学校和与985、211等重点本科院校学生之间的差距可能由多种因素造成,这些因素可能包括但不限于: 1. **入学标准**: 985和211工程院校通常有更高的入学标准和更严格的选拔过程。 你得使你自己适应更高的入学标准和更严格的选拔过程&am…...
清华镜像源
python在安装各种库的时候为了下载速度快,经常使用镜像源,下面是使用清华镜像源案例。其中的 xxx 表示要安装的库,如 requests。 pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple 安装requests案例:pip install r…...
大语言模型测评工具-ChatHub和ChatAll
背景 现在国内外拥有上百个大语言模型,在AI业务中,我们需要在其中选择一个合适业务模型,就需要对这些模型进行测试。手工去测试这么多模型效率一定不高,今天就介绍两个提高测评模型效率的工具 ChatHub和ChatAll。 介绍 ChatHub…...
使用redis分布式锁,不要把锁放在本地事务内部
在使用分布式锁的时候,习惯性的尽量缩小同步代码块的范围。 但是如果数据库隔离级别是可重复读,这种情况下不要把分布式锁加在Transactional注解的事务方法内部。 因为可能会出现这种情况: 线程1开启事务A后获取分布式锁,执行业务代码后在事务内释放了分布式锁。…...
Python学生信息管理系统(完整代码)
引言:(假装不是一个大学生课设)在现代教育管理中,学生管理系统显得尤为重要。这种系统能够帮助教育机构有效地管理学生资料、成绩、出勤以及其他教育相关活动,从而提高管理效率并减少人为错误。通过使用Python…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
