随着 Android 架构组件的稳定,我开始将所有基本 ViewModel
更新为 ViewModel
的新实现.据我了解,LiveData
的用法建议持有 Model
类,因为它更好地处理生命周期。
我喜欢使用 Data Binding
,因为它使 Java/Kotlin 端的代码更清晰,并且不需要“观察”值更改来更新 UI。然而,使用 Data Binding
的布局仅在 Model
(或 ViewModel)扩展 BaseObservable
时观察数据变化。而 LiveData
没有。我了解 LiveData
的主要目标之一是观察并以编程方式更新 UI,但对于简单的更新,Data Binding
非常有用。
这个问题已经被报告过(GitHub 和 Stack Overflow),最初说 1.0 版会有这个问题,现在说这个功能正在开发中。
为了同时使用 LiveData
和 Data 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
}
}
所以基本上我的 ObservableMutableLiveData
是 ObservableField
的副本使用 LiveData
来存储模型,通过这个实现,每次模型更新后布局都会更新。
问题是:
- 这是
LiveData
的错误实现吗?这个包装器是否“破坏”了LiveData
的功能,例如生命周期感知? - 在我的理解中,
LiveData
是新的ObservableField
。这是正确的吗?
最佳答案
对于那些遇到这个问题并像我一样寻找示例的人,这里有一个:
在布局 .xml
中放入 LiveData
元素及其类型:
<layout>
<data>
<variable
name="myString"
type="android.arch.lifecycle.MutableLiveData<String>"/>
</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/