
1. Overview
In this article, we will learn about the @Bindable annotation in Android.
We should apply the Bindable annotation to any getter accessor method of an Observable
class. Bindable will generate a field in the BR class to identify the field that has changed.
2. Basic concepts for @Bindable
The Data Binding Library generates a class named BR
in the module package for storing all the reactive values to handle.
When you update a reactive value, it notifies any reactive functions that depend on that value.
For example, BR contains the variables defined in the layout file. headline
, viewModel
are all variables declared in the layout XML files.
public class BR { public static final int _all = 0; public static final int headline = 1; public static final int viewModel = 2; }
<data> <variable name="headline" type="com.tedblob.data.remote.response.Headlines" /> </data>
2.1. Android Observable
An Observable class is a class that other classes can observe, then the “observer” classes are going to react and notify when they observe any change in the Observable class.
3. Android @Bindable
Assume a data class extends the BaseObservable
class making it an Observable
class.
1. You must annotate the getters with @Bindable annotation to inform Data Binding library that those classes are going to be bound.
2. The notifyPropertyChanged
function must be invoked on every setter of the corresponding bindable getter.
import android.databinding.BaseObservable import android.databinding.Bindable data class Item( private var _title: String ) : BaseObservable() { var title: String @Bindable get() = _title set(value) { _title = value notifyPropertyChanged(BR.title) } }
Alternatively, you can also use @Bindable
in your view model class. Note that the view model depends on the ObservableViewModel
.
For example, the below profile view model updates the popularity based on the number of likes. Whenever there are any new likes to the profile, we invoke the notifyPropertyChanged
to update the property popularity whose value is determined based on the number of likes.
class ProfileObservableViewModel : ObservableViewModel() { val likes = ObservableInt(0) fun onLike() { likes.increment() // You control when the @Bindable properties are updated using `notifyPropertyChanged()`. notifyPropertyChanged(BR.popularity) } @Bindable fun getPopularity(): Popularity { return likes.get().let { when { it > 9 -> Popularity.STAR it > 4 -> Popularity.POPULAR else -> Popularity.NORMAL } } } } enum class Popularity { NORMAL, POPULAR, STAR } private fun ObservableInt.increment() { set(get() + 1) }
You can also specify an optional list of property names in your @Bindable annotation that it depends on. If there is a change notification of the listed properties, this value will also be considered dirty and be refreshed.
For example, the name
property depends on firstName
and lastName
properties. Whenever any of these properties value changes, the name
property would be considered dirty and refreshed
public void getFirstName() { return this.firstName; } @Bindable public void getLastName() { return this.lastName; } @Bindable({"firstName", "lastName"}} public void getName() { return this.firstName + ' ' + this.lastName; }
4. Conclusion
To sum up, we have learned about the @Bindable annotation in Android.