[译]Android 数据绑定库 — 从可观察域到 LiveData 仅需两步

2024-01-26 10:24:15 浏览数 (2)

  • 原文地址:Android Data Binding Library — From Observable Fields to LiveData in two steps
  • 原文作者:Jose Alcérreca
  • 译文出自:掘金翻译计划
  • 本文永久链接:github.com/xitu/gold-m…
  • 译者:Rickon

数据绑定最重要的特性之一是可观察性。你可以用它绑定数据和 UI 元素,以便在数据更改时,相关元素在屏幕上更新。

默认情况下,普通基元和字符串是可被观察的,因此如果在数据绑定布局中使用它们,则在创建绑定时将使用它们的值,但对它们的后续更改会被忽略。

为了使对象可被观察,我们的数据绑定库中包含了一系列可被观察的类:ObservableBooleanObservableIntObservableDouble 和范型:ObservableField<T>。从现在开始,我们称这些为可观察域

几年后,作为第一波架构组件的一部分,我们发布了 LiveData,这是一个可被观察的。这是与数据绑定兼容的候选,因此我们添加了此功能。

LiveData 是可以感知生命周期的,对于可观察域而言,这并不是一个很大的优势,因为数据绑定库已经检查了视图何时处于活动状态。但是,LiveData 支持 Transformations 和很多架构组件,比如 RoomWorkManager

出于这些原因,建议你迁移到 LiveData。你只需要两步即可完成。

第一步:使用 LiveData 代替可观察域

如果你直接在数据绑定布局中使用可观察域,只需使用 LiveData<Something> 替换 ObservableSomething(或 ObservableField<Something>)。

修改前:

代码语言:javascript复制
<data>
    <import type="android.databinding.ObservableField"/>
    <variable 
        name="name" 
        type="ObservableField&lt;String>" />
</data>
…
<TextView
    android:text="@{name}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

Remember that %lt; is not a typo. You have to escape the < character inside XML layouts.

修改后:

代码语言:javascript复制
<data>
        <import type="android.arch.lifecycle.LiveData" />
        <variable
            name="name"
            type="LiveData&lt;String>" />
</data>
…
<TextView
    android:text="@{name}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

或者,如果你从 ViewModel(首选方法)或一个 presenter 层或控制器暴露可观察对象,则无需更改布局。只需在 ViewModel 中用 LiveData 替换那些 ObservableField

修改前:

代码语言:javascript复制
class MyViewModel : ViewModel() {
    val name = ObservableField<String>("Ada")
}

修改后:

代码语言:javascript复制
class MyViewModel : ViewModel() {
    private val _name = MutableLiveData<String>().apply { value = "Ada" }

    val name: LiveData<String> = _name // Expose the immutable version of the LiveData
}

第二步:设置 LiveData 的生命周期所有者

绑定类有一个名为 setLifecycleOwner 的方法,在从数据绑定布局中观察 LiveData 时必须调用该方法。

修改前:

代码语言:javascript复制
val binding = DataBindingUtil.setContentView<TheGeneratedBinding>(
    this,
    R.layout.activity_data_binding
)

binding.name = myLiveData // or myViewModel

修改后:

代码语言:javascript复制
val binding = DataBindingUtil.setContentView<TheGeneratedBinding>(
    this,
    R.layout.activity_data_binding
)

binding.lifecycleOwner = this // Use viewLifecycleOwner for fragments

binding.name = myLiveData // or myViewModel

注意:如果要设置 fragment 的内容,建议使用 fragment.viewLifecycleOwner(而不是 fragment 的生命周期)来处理潜在的分离的 fragments。


现在你可以使用你的带有 Transformations 和 MediatorLiveData 的 LiveData 对象。如果你不熟悉这些功能,可以参阅 “Fun with LiveData” 录像,来自 2018 Android 开发者大会。

文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。

0 人点赞