Using LiveData with Data Binding
Solution 1
The Android Studio 3.1 (currently in Canary 6) will fix this issue, since LiveData
can be used as observable field
:
Updates to Data Binding:
You can now use a LiveData object as an observable field in data binding expressions. The ViewDataBinding class now includes a new setLifecycle method that you need to use to use to observe LiveData objects.
Source: Android Studio 3.1 Canary 6 is now available
Solution 2
For those who came across this question looking for an example like I did, here's one:
In layout .xml
put the LiveData
element with it's 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>
In your code set it's value and the lifecycle owner:
MutableLiveData<String> myString = new MutableLiveData<>();
...
binding.setLifecycleOwner(this);
binding.setMyString(myString);
That's it :)
Note that the default value of LiveData
elements is null
so assign initial values to make sure you get the desired effect right away or use this to enforce nullability.
EDIT:
Use androidx.lifecycle.MutableLiveData<String>
as type if you use androidx
.
Solution 3
For androidx will be:
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>
And for Kotlin:
val myStr = MutableLiveData<String>()
...
binding.apply {
setLifecycleOwner(this)
this.myString = myStr
}
Good luck! :)
Solution 4
The accepted answer does not give an example. So here's one I've tested and it works.
In layout:
<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>
In fragment:
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
}
}
![Igor Escodro](https://i.stack.imgur.com/Z7oT9.jpg?s=256&g=1)
Igor Escodro
Updated on July 05, 2022Comments
-
Igor Escodro almost 2 years
With the stabilization of Android Architecture Components I started updating all my basic
ViewModel
s to the new implementation ofViewModel
. In my understanding, the usage ofLiveData
is recommended to hold theModel
class since it handles the lifecycle better.I like using
Data Binding
because it makes the code clearer in Java/Kotlin side and it is not needed to "watch" the value changes to update the UI. However the layout usingData Binding
only watch data changes if theModel
(or the ViewModel) extendsBaseObservable
andLiveData
does not. I understand the one of the main objectives ofLiveData
is to be observed and updates the UI programmatically but for simple updates,Data Binding
is very useful.This issue was already reported (GitHub and Stack Overflow) and first was said that the version 1.0 would have it and now is said that this feature is in development.
In order to use both
LiveData
andData Binding
, I created a very simple implementation of class that extendsBaseObservable
: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 } }
So basically my
ObservableMutableLiveData
is a copy ofObservableField
usingLiveData
to store the model and with this implementation, the layout updates after every model update.The questions are:
- Is this a bad implementation of
LiveData
? Does this wrapper "breaks" the functionalities ofLiveData
, such as be lifecycle-aware? - In my understanding,
LiveData
is the newObservableField
. Is this correct?
- Is this a bad implementation of