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

Android-Kotlin基础(Jetpack②-Data Binding)

功能需求
显示用户的姓名、年龄、身份(学生 / 上班族)
点击按钮切换用户信息

一、传统方式实现

1. 布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/tvName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"/><TextViewandroid:id="@+id/tvAge"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"/><TextViewandroid:id="@+id/tvIdentity"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"/><Buttonandroid:id="@+id/btnChange"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="切换用户"android:layout_marginTop="16dp"/></LinearLayout>
2. Activity 代码(MainActivity.kt)
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextViewclass MainActivity : AppCompatActivity() {// 声明所有需要操作的控件private lateinit var tvName: TextViewprivate lateinit var tvAge: TextViewprivate lateinit var tvIdentity: TextViewprivate lateinit var btnChange: Button// 数据private var currentUser = User("张三", 20, true)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 1. 手动绑定所有控件(最繁琐的步骤)initViews()// 2. 手动更新UIupdateUI()// 3. 手动设置点击事件btnChange.setOnClickListener {// 切换数据currentUser = if (currentUser.name == "张三") {User("李四", 25, false)} else {User("张三", 20, true)}// 手动更新UIupdateUI()}}// 初始化所有控件(findViewById重复劳动)private fun initViews() {tvName = findViewById(R.id.tvName)tvAge = findViewById(R.id.tvAge)tvIdentity = findViewById(R.id.tvIdentity)btnChange = findViewById(R.id.btnChange)}// 手动更新所有控件内容private fun updateUI() {tvName.text = currentUser.nametvAge.text = "年龄:${currentUser.age}"tvIdentity.text = if (currentUser.isStudent) "学生" else "上班族"}// 数据类data class User(val name: String,val age: Int,val isStudent: Boolean)
}

二、Data Binding 方式实现

1. 布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="user"type="com.example.databindingdemo.MainActivity.User" /></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><!-- 直接绑定数据,无需id --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.name}"  <!-- 数据绑定 -->android:textSize="18sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{`年龄:` + user.age}"  <!-- 表达式拼接 -->android:layout_marginTop="8dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.isStudent ? `学生` : `上班族`}"  <!-- 条件判断 -->android:layout_marginTop="8dp"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="切换用户"android:layout_marginTop="16dp"android:onClick="@{() -> user.change()}"  <!-- 绑定点击事件 -->android:enabled="@{user.name.isNotEmpty()}"/>  <!-- 动态控制启用状态 --></LinearLayout>
</layout>
2. Activity 代码(MainActivity.kt)
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.databindingdemo.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {// 只需要声明Binding对象private lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 初始化Binding(替代setContentView和findViewById)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 绑定数据(自动更新UI)binding.user = User("张三", 20, true)}// 数据类(包含修改逻辑)inner class User(val name: String,val age: Int,val isStudent: Boolean) {// 点击事件处理fun change() {// 直接修改绑定的数据,UI自动更新binding.user = if (name == "张三") {User("李四", 25, false)} else {User("张三", 20, true)}}}
}

三、核心差异对比

对比维度传统方式Data Binding 方式
控件获取需手动写大量 findViewById自动生成 Binding 类,直接通过属性访问
UI 更新需手动调用 setText() 等方法数据变化后自动更新 UI
代码量多(初始化、更新逻辑重复)少(省略模板代码)
可读性数据与 UI 关联分散在代码中数据与 UI 关联集中在布局中
维护成本高(修改 UI 需同时改代码)低(布局与数据绑定一目了然)
错误检查运行时可能因控件 ID 错误崩溃编译时检查绑定表达式,提前发现错误
事件处理需手动设置 setOnClickListener布局中直接绑定事件,逻辑更集中

Data Binding 方式的区别

当使用 Data Binding 时,布局文件会被自动处理成一个 Binding 类(比如 activity_main.xml 会生成 ActivityMainBinding 类),这个类相当于布局文件的 "代码代表"。

第一行:binding = ActivityMainBinding.inflate(layoutInflater)
  • ActivityMainBinding:自动生成的类,名字是布局文件名(下划线转驼峰)+ Binding
  • inflate(layoutInflater):这是解析布局的过程,相当于传统的 "把 XML 变成 View"
  • 执行后,binding 对象就持有了整个布局的所有控件和数据绑定能力
第二行:setContentView(binding.root)
  • binding.root:指的是布局文件的根节点(比如你布局中的 LinearLayout 或 ConstraintLayout
  • 这行代码的作用和传统 setContentView(R.layout.xxx) 一样:让 Activity 显示这个根节点对应的界面
  • 区别是:传统方式直接传布局 ID,Data Binding 方式传已经解析好的根 View

形象比喻

可以把布局文件想象成 "设计图纸":

  • 传统方式:直接告诉 Activity "用图纸 ID 302 建房子"(setContentView(R.layout.xxx)),之后需要自己去房子里找各个房间(findViewById)。
  • Data Binding 方式:先请一个 "施工队"(ActivityMainBinding.inflate())根据图纸建好房子,得到一个 "房屋管理手册"(binding),手册里记录了所有房间的位置。然后告诉 Activity "就用这个建好的房子"(setContentView(binding.root)),之后想找哪个房间,直接查手册就行(binding.tvName)。

http://www.dtcms.com/a/318778.html

相关文章:

  • 国产化Excel处理组件Spire.XLS教程:使用 C# 将 DataTable 导出为 Excel 文件
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 东莞立晟精密硅胶科技有限公司将携重磅产品亮相 AUTO TECH China 2025 广州国际汽车技术展
  • 计算机网络1-4:计算机网络的定义和分类
  • 汽车娱乐信息系统域控制器的网络安全开发方案
  • FPGA实战:用PL端串口发送Hello world
  • 【C/C++】C++引用和指针的对比
  • 29-数据仓库与Apache Hive-创建库、创建表
  • 树莓派安装OpenCV环境
  • 【CDA案例】数据分析案例拆解:解锁数据分析全流程!
  • 微服务、服务网格、Nacos架构与原理
  • mapbox进阶,mapbox-gl-draw绘图插件扩展,绘制新增、编辑模式支持点、线、面的捕捉
  • Linux系统编程--权限管理
  • 在NVIDIA Orin上用TensorRT对YOLO12进行多路加速并行推理时内存泄漏(下)
  • Redis为什么要引入多线程?
  • 如何在GPU上安装使用Docker
  • 【AI】——SpringAI通过Ollama本地部署的Deepseek模型实现一个对话机器人(二)
  • 用 tcpdump 捕获网络数据包
  • RTSP播放器技术详解:功能支持、平台覆盖与快速集成指南
  • PostgreSQL 强制索引:当重复数据让优化器“失明”时的解决方案
  • centos系统sglang单节点本地部署大模型
  • Sklearn 机器学习 数据降维PCA 自己实现PCA降维算法
  • 如何打造一支AI时代下的IT团队,为企业战略目标快速赋能
  • Java面试宝典:JVM的垃圾收集算法
  • MCU中的晶振(Crystal Oscillator)
  • 【Zephyr】02_从零教你开发芯片级ADC驱动(HAL层篇)
  • 每日五个pyecharts可视化图表-bars(6)
  • 嵌入式硬件中MOSFET基本原理与实现
  • 基于 Socket.IO 实现 WebRTC 音视频通话与实时聊天系统(Spring Boot 后端实现)
  • C语言中级_动态内存分配、指针和常量、各种指针类型、指针和数组、函数指针