目录
  1. 1. 一、基础使用
  2. 2. 二、BindingAdapter:自定义属性
  3. 3. 三、Observable 与双向绑定
  4. 4. 四、DataBinding vs ViewBinding vs findViewById
  5. 5. 面试常考问题
JetPack全家桶(九)之DataBinding数据绑定

DataBinding 是 Jetpack 中实现声明式 UI 绑定的库,它将数据对象直接绑定到布局文件,在编译期生成绑定类,消除 findViewById 样板代码,并支持双向绑定与自定义绑定适配器。

一、基础使用

Step 1:启用 DataBinding

// app/build.gradle
android {
buildFeatures {
dataBinding = true
}
}

Step 2:布局声明

<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.example.User" />
<variable
name="handler"
type="com.example.ClickHandler" />
</data>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:text="@{user.name}"
android:textColor="@{user.isVip ? @color/red : @color/gray}"
android:onClick="@{() -> handler.onUserClick(user)}" />

<EditText
android:text="@={user.email}" />
<!-- @= 表示双向绑定 -->
</LinearLayout>
</layout>

Step 3:Activity 中使用

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.user = User("张三", isVip = true)
binding.handler = ClickHandler()
// binding.lifecycleOwner = this // 为 LiveData 绑定提供生命周期
}
}

编译期自动生成 ActivityMainBinding 类,包含所有视图引用(免去 findViewById)和数据绑定逻辑。

二、BindingAdapter:自定义属性

@BindingAdapter("imageUrl", "placeholder")
fun loadImage(view: ImageView, url: String?, placeholder: Drawable?) {
Glide.with(view.context)
.load(url)
.placeholder(placeholder ?: ColorDrawable(Color.GRAY))
.into(view)
}

布局中直接使用:app:imageUrl="@{user.avatar}",无需在 Java/Kotlin 代码中手动调用图片加载库。

三、Observable 与双向绑定

ObservableField 让单个字段变更自动通知 UI:

class User {
val name = ObservableField<String>()
val email = ObservableField<String>()
val isVip = ObservableBoolean()
}
// 赋值:user.name.set("李四") —— 自动更新 UI

双向绑定@={})在 EditText 等可编辑控件上同步数据变化。结合 InverseBindingAdapter 可自定义转换逻辑。

四、DataBinding vs ViewBinding vs findViewById

特性 DataBinding ViewBinding findViewById
布局表达式 支持 不支持 不支持
双向绑定 支持 不支持 不支持
编译时安全 支持 支持 不支持
生成方式 注解处理 + 代码生成 代码生成 运行时反射
构建速度 较慢 最快(但低效)
适用场景 MVVM 中需要数据驱动 UI 仅需 View 引用 仅原型 / 已废弃

面试常考问题

Q1:DataBinding 的核心原理?

DataBinding 在编译时扫描 <layout> 标签包裹的 XML 文件,通过 annotation processor 生成 Binding 类(继承自 ViewDataBinding)。该类持有所有 View 引用,并在 executeBindings() 中执行布局表达式。数据变更通过 Observable 接口回调触发绑定重新执行。源码入口:androidx.databinding.DataBindingUtil

Q2:@BindingAdapter 的 override 参数有何作用?

当多个 @BindingAdapter 注解了相同的属性名时,需要指定 requireAll = false 表示不必所有适配器都执行,以及 override = true 来决定优先级覆盖策略。这用于在全局注册多个同属性适配器时的冲突解决。

Q3:DataBinding 如何避免 null 安全导致的崩溃?

DataBinding 生成的代码在 setter 调用前自动进行 null 检查。例如 android:text="@{user.name}" 生成代码等价于 if (user != null && user.getName() != null) textView.setText(...)。此外 @BindingAdapter 的参数默认 nullable,可通过 @NonNull 注解覆盖。

打赏
  • 微信
  • 支付宝

评论