将LiveData与数据绑定结合使用

时间:2017-12-09 09:34:21

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

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

我喜欢使用Data Binding,因为它使代码在Java / Kotlin方面更加清晰,并且不需要"观看"值更改以更新UI。但是,如果Data Binding(或ViewModel)扩展BaseObservableModel不扩展,则使用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的错误实现吗?这个包装器是否会破坏&#34; LiveData的功能,例如生命周期感知?
  • 据我了解,LiveData是新ObservableField。这是对的吗?

4 个答案:

答案 0 :(得分:14)

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

在布局.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,因此请指定初始值,以确保立即获得所需效果,或使用this强制执行可为空性。

答案 1 :(得分:13)

Android Studio 3.1(目前位于Canary 6中)将解决此问题,因为LiveData可用作observable field

  

数据绑定的更新:

     

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

来源:Android Studio 3.1 Canary 6 is now available

答案 2 :(得分: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
    }
}

答案 3 :(得分:0)

对于androidx,将是:

  

androidx.lifecycle.MutableLiveData

<layout>
    <data>
        <variable
            name="myString"
            type="androidx.lifecycle.MutableLiveData;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
        }

祝你好运! :)