news 2026/4/24 3:53:13

Adroid Data Binding数据绑定对比(findViewXX、ButterKnife)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Adroid Data Binding数据绑定对比(findViewXX、ButterKnife)

9.1 数据绑定基础对比

// 传统方式 - findViewByIdclassUserActivity:AppCompatActivity(){privatelateinitvartvName:TextViewprivatelateinitvartvAge:TextViewprivatelateinitvartvEmail:TextViewprivatelateinitvartvPhone:TextViewprivatelateinitvartvAddress:TextViewprivatelateinitvarbtnUpdate:ButtonoverridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_user)// 大量的 findViewById 调用tvName=findViewById(R.id.tvName)tvAge=findViewById(R.id.tvAge)tvEmail=findViewById(R.id.tvEmail)tvPhone=findViewById(R.id.tvPhone)tvAddress=findViewById(R.id.tvAddress)btnUpdate=findViewById(R.id.btnUpdate)// 加载用户数据loadUserData()}privatefunloadUserData(){valuser=userRepository.getUser("123")// 手动更新每个 ViewtvName.text=user.name tvAge.text=user.age.toString()tvEmail.text=user.email tvPhone.text=user.phone tvAddress.text=user.address}privatefunupdateUser(user:User){// 手动更新每个 ViewtvName.text=user.name tvAge.text=user.age.toString()tvEmail.text=user.email tvPhone.text=user.phone tvAddress.text=user.address}}// ===================== 1. ButterKnife 绑定控件 =====================@BindView(R.id.tv_name)// 对应布局 TextView idTextView tvName;@BindView(R.id.tv_age)TextView tvAge;
// - ButterKnife@BindView(R.id.tv_name)// 对应布局 TextView idTextViewtvName;@BindView(R.id.tv_age)TextViewtvAge;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 1. 初始化 ButterKnifeButterKnife.bind(this);// 3. 直接赋值!setDataToView();}

传统方式的问题

问题说明影响
样板代码大量的 findViewById 调用代码冗余,难以维护
手动更新需要手动更新每个 View容易遗漏,容易出错
可读性差UI 逻辑与业务逻辑混合代码可读性差
类型不安全使用字符串 ID 获取 View运行时错误
难以测试UI 逻辑与业务逻辑耦合难以单元测试
// 使用 Data BindingclassUserActivity:AppCompatActivity(){privatelateinitvarbinding:ActivityUserBindingprivatelateinitvarviewModel:UserViewModeloverridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)// 设置绑定binding=DataBindingUtil.setContentView(this,R.layout.activity_user)viewModel=ViewModelProvider(this).get(UserViewModel::class.java)// 设置数据binding.viewModel=viewModel binding.lifecycleOwner=this// 数据更新会自动反映到 UI 在xml布局文件中使用UserviewModel.loadUser("123")}}

Data Binding 的优势

优势说明
消除样板代码自动生成 View 的引用,无需 findViewById
自动 UI 更新数据变化自动反映到 UI
类型安全编译时检查,避免运行时错误
代码简洁UI 逻辑与业务逻辑分离
易于测试UI 逻辑可以独立测试

9.2 Data Binding 快速入门

9.2.1 启用 Data Binding

在 build.gradle 中启用

android { // ... dataBinding { enabled = true } }

9.2.2 创建布局文件

布局文件结构

<?xml version="1.0" encoding="utf-8"?><layoutxmlns: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><!-- 定义数据变量 --><variablename="user"type="com.example.app.model.User"/><variablename="viewModel"type="com.example.app.viewmodel.UserViewModel"/><importtype="android.view.View"/></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ui.user.UserActivity"><!-- 用户名 --><TextViewandroid:id="@+id/tvName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.name}"android:textSize="20sp"android:textStyle="bold"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="50dp"/><!-- 年龄 --><TextViewandroid:id="@+id/tvAge"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{@string/age_format(user.age)}"android:textSize="16sp"app:layout_constraintTop_toBottomOf="@id/tvName"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="20dp"/><!-- 邮箱 --><TextViewandroid:id="@+id/tvEmail"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.email}"android:textSize="16sp"app:layout_constraintTop_toBottomOf="@id/tvAge"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="20dp"/><!-- 电话 --><TextViewandroid:id="@+id/tvPhone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.phone}"android:textSize="16sp"app:layout_constraintTop_toBottomOf="@id/tvEmail"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="20dp"/><!-- 地址 --><TextViewandroid:id="@+id/tvAddress"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.address}"android:textSize="16sp"app:layout_constraintTop_toBottomOf="@id/tvPhone"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="20dp"/><!-- 更新按钮 --><Buttonandroid:id="@+id/btnUpdate"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="更新"android:onClick="@{() -> viewModel.updateUser()}"android:visibility="@{viewModel.isLoading ? View.GONE : View.VISIBLE}"app:layout_constraintTop_toBottomOf="@id/tvAddress"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="30dp"/><!-- 加载进度条 --><ProgressBarandroid:id="@+id/progressBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="@{viewModel.isLoading ? View.VISIBLE : View.GONE}"app:layout_constraintTop_toBottomOf="@id/tvAddress"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"android:layout_marginTop="30dp"/></androidx.constraintlayout.widget.ConstraintLayout></layout>

9.2.3 在 Activity 中使用 Data Binding

/** * 用户 Activity */classUserActivity:AppCompatActivity(){privatelateinitvarbinding:ActivityUserBindingprivatelateinitvarviewModel:UserViewModeloverridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)// 使用 DataBindingUtil.setContentView 代替 setContentViewbinding=DataBindingUtil.setContentView(this,R.layout.activity_user)viewModel=ViewModelProvider(this).get(UserViewModel::class.java)// 设置数据到绑定对象binding.viewModel=viewModel binding.lifecycleOwner=this// 加载用户数据valuserId=intent.getStringExtra("USER_ID")?:""viewModel.loadUser(userId)}}

以上是对比以及快速入门参考案例。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 3:51:37

3分钟上手!用aws-cli玩转Redshift数据仓库管理

3分钟上手&#xff01;用aws-cli玩转Redshift数据仓库管理 【免费下载链接】aws-cli Universal Command Line Interface for Amazon Web Services 项目地址: https://gitcode.com/GitHub_Trending/aw/aws-cli AWS CLI&#xff08;Amazon Web Services Command Line Inte…

作者头像 李华
网站建设 2026/4/24 3:47:16

5分钟解决Dokploy数据库启动失败:从日志分析到实战修复

5分钟解决Dokploy数据库启动失败&#xff1a;从日志分析到实战修复 【免费下载链接】dokploy Open Source Alternative to Vercel, Netlify and Heroku. 项目地址: https://gitcode.com/GitHub_Trending/do/dokploy Dokploy作为开源的Vercel、Netlify和Heroku替代方案&a…

作者头像 李华
网站建设 2026/4/24 3:46:22

Spring Boot 集成 Nebula Graph(国产图库) 实现图谱分析

一. 引言 在处理复杂关系数据时,图数据库展现出了传统关系型数据库无法比拟的优势。Nebula Graph 作为一款国产高性能分布式图数据库,以其优异的性能和可扩展性在众多图数据库中脱颖而出。 二. Nebula Graph 简介 2.1 核心特性 高性能:专为大规模图数据设计,支持高并发查…

作者头像 李华
网站建设 2026/4/24 3:45:43

WaveTools鸣潮工具箱终极指南:5分钟解锁120FPS极致游戏体验

WaveTools鸣潮工具箱终极指南&#xff1a;5分钟解锁120FPS极致游戏体验 【免费下载链接】WaveTools &#x1f9f0;鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools WaveTools鸣潮工具箱是一款专为《鸣潮》玩家设计的开源性能优化神器&#xff0c;能够…

作者头像 李华