android - 将 LiveData 与数据绑定(bind)一起使用

标签 android kotlin android-databinding android-architecture-components android-mvvm

随着 Android 架构组件的稳定,我开始将所有基本 ViewModel 更新为 ViewModel 的新实现.据我了解,LiveData 的用法建议持有 Model 类,因为它更好地处理生命周期。

我喜欢使用 Data Binding,因为它使 Java/Kotlin 端的代码更清晰,并且不需要“观察”值更改来更新 UI。然而,使用 Data Binding 的布局仅在 Model(或 ViewModel)扩展 BaseObservable 时观察数据变化。而 LiveData 没有。我了解 LiveData 的主要目标之一是观察并以编程方式更新 UI,但对于简单的更新,Data Binding 非常有用。

这个问题已经被报告过(GitHubStack Overflow),最初说 1.0 版会有这个问题,现在说这个功能正在开发中。

为了同时使用 LiveDataData Binding,我创建了一个扩展 BaseObservable 的类的非常简单的实现:

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.databinding.BaseObservable

class ObservableMutableLiveData<T>() : BaseObservable() {

    private var data: MutableLiveData<T> = MutableLiveData()

    constructor(data: T) : this() {
        this.data.value = data
    }

    public fun set(value: T) {
        if (value != data.value) {
            data.value = value
            notifyChange()
        }
    }

    public fun get(): T? {
        return data.value
    }

    public fun getObservable(): LiveData<T> {
        return data
    }
}

所以基本上我的 ObservableMutableLiveDataObservableField 的副本使用 LiveData 来存储模型,通过这个实现,每次模型更新后布局都会更新。

问题是:

  • 这是 LiveData 的错误实现吗?这个包装器是否“破坏”了 LiveData 的功能,例如生命周期感知?
  • 在我的理解中,LiveData 是新的ObservableField。这是正确的吗?

最佳答案

对于那些遇到这个问题并像我一样寻找示例的人,这里有一个:

在布局 .xml 中放入 LiveData 元素及其类型:

<layout>
    <data>
        <variable
            name="myString"
            type="android.arch.lifecycle.MutableLiveData&lt;String&gt;"/>
    </data>

    ...

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text='@{myString}'
        ...
     />

    ...

</layout>

在您的代码集中,它的值(value)和生命周期所有者:

MutableLiveData<String> myString = new MutableLiveData<>();

...

binding.setLifecycleOwner(this);
binding.setMyString(myString);

就是这样:)

请注意,LiveData 元素的默认值为 null,因此请分配初始值以确保您立即获得所需的效果或使用 this强制可空性。

编辑: 如果您使用 androidx,请使用 androidx.lifecycle.MutableLiveData<String> 作为类型。

关于android - 将 LiveData 与数据绑定(bind)一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47727211/

相关文章:

android - 如何在 SeekBar 拇指中间添加 TextView?

java - 没有验证证明无法创建 PhoneAuthCredential?

android - Jetpack Compose Navigation - 底部导航多个返回堆栈 - 查看模型范围问题

java - 针对多个 XSD(存储为资源)验证 XML。 Spring 启动

android - 禁用某些布局的数据绑定(bind)

android - 如何将数据变量传递给包含的布局?

android - LiveData 的更新值丢失

java - 为什么在 Android 中使用 XML 来创建 UI 布局?

android - 如何等待协程结束

android - 当 edittext 的默认文本为浮点值时,编辑文本光标重置为左侧