web-dev-qa-db-ja.com

データバインディングでのLiveDataの使用

Android Architecture Components)の安定化により、すべての基本的なViewModelsを ViewModel の新しい実装に更新し始めました。 、ライフサイクルをより適切に処理するため、LiveDataクラスを保持するために Model を使用することをお勧めします。

Data Bindingを使用すると、Java/Kotlin側でコードが明確になり、UIを更新するために値の変更を「監視」する必要がないため、使用するのが好きです。ただし、Data Bindingを使用するレイアウトは、Model(またはViewModel)が BaseObservable を拡張し、LiveDataが拡張しない場合にのみデータを監視します。 LiveDataの主な目的の1つが観察され、プログラムでUIを更新することを理解していますが、単純な更新にはData Bindingが非常に便利です。

この問題はすでに報告されており( GitHub および Stack 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です。これは正しいです?
22
Igor Escodro

LiveDataobservable fieldとして使用できるため、Android Studio 3.1(現在Canary 6))はこの問題を修正します。

データバインディングの更新:

LiveDataオブジェクトをデータバインディング式の監視可能なフィールドとして使用できるようになりました。 ViewDataBindingクラスには、LiveDataオブジェクトの監視に使用する必要がある新しいsetLifecycleメソッドが含まれるようになりました。

ソース: Android Studio 3.1 Canary 6が利用可能になりました

13
Igor Escodro

私のような例を探しているこの質問に出くわした人のために、ここに一つあります:

レイアウト.xmlLiveData要素とそのタイプを入力します。

<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 を使用してNULL値を許可します。

16
Sir Codesalot

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
        }

幸運を! :)

0
Serg Burlaka