Avec la stabilisation des composants de l'architecture Android, j'ai commencé à mettre à jour tous mes ViewModel
s de base vers la nouvelle implémentation de ViewModel
. D'après ce que j'ai compris, il est recommandé d'utiliser LiveData
pour contenir la classe Model
car elle gère mieux le cycle de vie.
J'aime utiliser Data Binding
car cela clarifie le code côté Java/Kotlin et qu'il n'est pas nécessaire de "surveiller" les modifications de valeur pour mettre à jour l'interface utilisateur. Cependant, la disposition utilisant uniquement Data Binding
observe les données, si les modifications apportées à Model
(ou au ViewModel) sont étendues BaseObservable
et LiveData
ne le sont pas. Je comprends que l’un des objectifs principaux de LiveData
doit être observé et met à jour l’UI par programme, mais pour les mises à jour simples, Data Binding
est très utile.
Ce problème avait déjà été signalé ( GitHub et Stack Overflow ) et d’abord il a été dit que la version 1.0 l’aurait et on dit maintenant que cette fonctionnalité est en développement.
Afin d'utiliser à la fois LiveData
et Data Binding
, j'ai créé une implémentation très simple de la classe qui étend 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
}
}
Donc, fondamentalement, mon ObservableMutableLiveData
est une copie de ObservableField
qui utilise LiveData
pour stocker le modèle et avec cette implémentation, la mise à jour est mise à jour après chaque mise à jour du modèle.
Les questions sont:
LiveData
? Ce wrapper "casse-t-il" les fonctionnalités de LiveData
, telles que le cycle de vie?LiveData
est le nouveau ObservableField
. Est-ce correct?Android Studio 3.1 (actuellement dans Canary 6) résoudra ce problème, car LiveData
peut être utilisé comme observable field
:
Mises à jour de la liaison de données:
Vous pouvez maintenant utiliser un objet LiveData en tant que champ observable dans les expressions de liaison de données. La classe ViewDataBinding inclut désormais une nouvelle méthode setLifecycle que vous devez utiliser pour observer les objets LiveData.
Source: Android Studio 3.1 Canary 6 est maintenant disponible
Pour ceux qui ont trouvé cette question en cherchant un exemple comme moi, en voici une:
Dans la mise en page .xml
, mettez l'élément LiveData
avec son type:
<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>
Dans votre code, définissez sa valeur et le propriétaire du cycle de vie:
MutableLiveData<String> myString = new MutableLiveData<>();
...
binding.setLifecycleOwner(this);
binding.setMyString(myString);
C'est tout :)
Notez que la valeur par défaut de LiveData
elements est null
. Par conséquent, affectez des valeurs initiales pour vous assurer d'obtenir immédiatement l'effet souhaité ou utilisez this pour appliquer la nullabilité.
Pour Androidx sera:
androidx.lifecycle.MutableLiveData
<layout>
<data>
<variable
name="myString"
type="androidx.lifecycle.MutableLiveData;String>"/>
</data>
...
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text='@{myString}'
...
/>
...
</layout>
Et pour Kotlin:
val myStr = MutableLiveData<String>()
...
binding.apply {
setLifecycleOwner(this)
this.myString = myStr
}
Bonne chance! :)