Data Binding With LiveData In Kotlin part 2
4 min readOct 19, 2022
Agenda
- One-Way Data Binding
- Two-Way Data Binding
- Data Binding with ViewModel & LiveData
One-Way Data Binding
- In one-way data binding, only the data source can update the views on data change, views cannot update the data source.
- We use one-way data binding for read-only views to update views on data change.
android:text=”@{employee.name}”
- The above is the syntax for one-way data binding. here you see we are updating the text of the view using the name attribute of the employee data variable.
Two-Way Data Binding
- In two-way data binding, the view and data source can update each other.
- Both the view and data source are in sync. Every change in view will be reflected on the data source and vice versa.
- It is generally used with editable fields.
android:text=”@={mainViewModel.nameLiveData}”
- It has a syntax similar to one-way data binding. It has just 1 char of difference ie “=”.
- Here we are updating the text field using the mutable live data name of mainViewModel and vice versa.
ViewModel Class
class MainViewModel: ViewModel() {
private val profileObject = MutableLiveData("Android Developer")
val profileLiveData: LiveData<String> get() = profileObject
fun updateProfile() {
profileObject.value = "Full Stack Developer"
}
}
- we have created a ViewModel class MainViewModel.
- we have created a LiveData object profileObject and a getter variable profileLiveData, profileLiveData is used by methods outside MainViewModel to fetch profileObject value and restrict them from changing it.
- we have created a function updateProfile to update LiveData profileObject value.
Layout File
- we have created a data variable mainViewModel of type MainViewModel.
- we are updating the text view with the help of LiveData. The text will get updated whenever there is a change in the profileLiveData value.
- In text view one-way data binding is taking place, the data source is updating the view but the view is not updating the data source.
- Inside Button, we have created a lambda function which is calling updateProfile method which is updating the LiveData object responsible for TextView text.
Activity File
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding get() = _binding!!
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding.mainViewModel = mainViewModel
binding.lifecycleOwner = this
}
}
- Here we are inflating the layout and creating the binding instance using generated DataBinding class.
- We have also created a ViewModel object mainViewModel.
binding.mainViewModel = mainViewModel
- Here we assign mainViewModel to the data variable object so that it can access the ViewModel objects and method and update the layout.
binding.lifecycleOwner = this
- It sets the activity as the lifecycleOwner and we can use this activity to observe changes in LiveData used in the binding class.
Note
- I found the minimum lag in updating views using data binding.
- I tried view binding and manual methods to update views but they lag and result in a bad user experience.
One-Way Data Binding Example
- Here I have used one-way data binding to update the profile using LiveData.
Two-Way Data Binding Example
- Here I have used two-way data binding to update the profile using LiveData.
- LiveData is updating textView and EditText.
- EditText is updating LiveData as well.
- So whenever we change profile text in EditText, it updates the LiveData which eventually updates the TextView.
<EditText
android:id="@+id/editTextProfile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="@={mainViewModel.profileObject}"
.../>