30

随着 Android 架构组件的稳定,我开始将所有基本组件更新ViewModelViewModel. 据我了解,LiveData建议使用 来保存Model类,因为它可以更好地处理生命周期。

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

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

为了同时使用LiveDataand 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. 这个对吗?
4

4 回答 4

35

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

在布局.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>

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

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

...

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

而已 :)

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

编辑androidx.lifecycle.MutableLiveData&lt;String&gt;如果您使用,请用作类型androidx

于 2018-05-09T06:27:25.257 回答
15

Android Studio 3.1(目前在 Canary 6 中)将解决这个问题,因为LiveData可以用作observable field

数据绑定更新:

您现在可以将 LiveData 对象用作数据绑定表达式中的可观察字段。ViewDataBinding 类现在包含一个新的 setLifecycle 方法,您需要使用它来观察 LiveData 对象。

来源:Android Studio 3.1 Canary 6 现已推出

于 2017-12-21T18:12:56.327 回答
1

对于 androidx 将是:

androidx.lifecycle.MutableLiveData

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

    ...

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

    ...

</layout>

对于 Kotlin:

  val myStr = MutableLiveData<String>()

...

 binding.apply {
            setLifecycleOwner(this)
            this.myString = myStr
        }

祝你好运!:)

于 2019-02-05T20:08:53.623 回答
1

接受的答案没有举例说明。所以这是我测试过的一个,它有效。

在布局中:

<layout>
    <data>
        <variable
            name="viewmodel"
            type="com.abc.xyz.viewmodels.MyViewModel"/>
    </data>

    ...

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

    ...

</layout>

在片段中:

override fun onCreateView(inflater: LayoutInflater, 
         container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val binding: FragmentAlbumBinding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_album, container, false)
        binding.apply {
            fragment = this
            viewModel = albumViewModel
            lifecycleOwner = this
    }
}
于 2020-06-22T11:28:59.570 回答