it-swarm.com.de

Verwenden von LiveData mit Datenbindung

Mit der Stabilisierung der Android-Architekturkomponenten begann ich, alle grundlegenden ViewModels auf die neue Implementierung von ViewModel zu aktualisieren. In meinem Verständnis wird die Verwendung von LiveData empfohlen, um die Model-Klasse zu speichern, da sie den Lebenszyklus besser handhabt.

Ich mag die Verwendung von Data Binding, da der Code in Java/Kotlin-Seite klarer wird und es nicht erforderlich ist, die Wertänderungen zu "beobachten", um die Benutzeroberfläche zu aktualisieren. Das Layout mit Data Binding überwacht jedoch nur Datenänderungen, wenn die Model (oder das ViewModel) BaseObservable und LiveData nicht erweitert. Ich verstehe, dass eines der Hauptziele von LiveData die Beobachtung ist und die Benutzeroberfläche programmgesteuert aktualisiert. Für einfache Updates ist Data Binding jedoch sehr nützlich.

Dieses Problem wurde bereits gemeldet ( GitHub und Stack Overflow ) und zuerst wurde gesagt, dass die Version 1.0 es haben würde, und nun wird gesagt, dass sich dieses Feature in der Entwicklung befindet.

Um sowohl LiveData als auch Data Binding zu verwenden, habe ich eine sehr einfache Implementierung der Klasse erstellt, die BaseObservable erweitert:

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
    }
}

Im Grunde ist meine ObservableMutableLiveData eine Kopie von ObservableField , die LiveData zum Speichern des Modells verwendet, und mit dieser Implementierung wird das Layout nach jeder Modellaktualisierung aktualisiert.

Die Fragen sind:

  • Ist dies eine schlechte Implementierung von LiveData? Bricht dieser Wrapper die Funktionen von LiveData, z. B. lebenszyklusbewusst?
  • Nach meinem Verständnis ist LiveData die neue ObservableField. Ist das richtig?
19
Igor Escodro

Das Android Studio 3.1 (derzeit in Canary 6) wird dieses Problem beheben, da LiveData als observable field verwendet werden kann:

Aktualisierungen der Datenbindung:

Sie können ein LiveData-Objekt jetzt als beobachtbares Feld in Datenbindungsausdrücken verwenden. Die ViewDataBinding-Klasse enthält jetzt eine neue setLifecycle-Methode, die Sie zum Beobachten von LiveData-Objekten verwenden müssen.

Quelle: Android Studio 3.1 Canary 6 ist jetzt verfügbar

12
Igor Escodro

Für diejenigen, die auf diese Frage gestoßen sind und nach einem Beispiel wie ich gesucht haben, ist hier eines:

Fügen Sie im Layout .xml das LiveData-Element mit seinem Typ ein:

<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>

In Ihrem Codesatz wird der Wert und der Lebenszyklusbesitzer angezeigt:

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

...

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

Das ist es :)

Beachten Sie, dass der Standardwert von LiveData-Elementen null ist, also weisen Sie Anfangswerte zu, um sicherzustellen, dass Sie den gewünschten Effekt sofort erzielen, oder verwenden Sie this , um die Nullfähigkeit durchzusetzen.

13
Sir Codesalot

Für Android wird es sein:

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>

Und für Kotlin:

  val myStr = MutableLiveData<String>()

...

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

Viel Glück! :)

0
Serg Burlaka