Data Binding Kotlin Login Screen using MVVM
This document explains databinding in Kotlin with Login Screen
What is Data Binding in Android ?
Data Binding is a library that allows you to bind UI components in your layout to Data sources in your app using a declarative format rather than doing it programmatically.
Advantages of Data Binding ?
Binding UI components in your layout using declarative format rather than doing it programmatically improves app performance and reduces memory leaks.
Calls like findViewByID is not needed when we bind UI components of our layout to data sources of our app.
Activities and Fragments maintainability will be made simpler as thecalls to findViewBy Id is reduced.
With out Data Binding :
findViewById<TextView>(R.id.sample_text).apply {
text = viewModel.userName
}
With Data Binding (In Layout only no need of findviewbyid in activity)
<TextView
android:text="@{viewmodel.userName}" />
Example and step-by-step explanation to create login screen using data binding
Step 1: set dataBinding enabled = true in your App level build.gradle as below:
dataBinding {
enabled = true
}
Step 2:
Create a data class that extends BaseObservable.
This is a POJO class in Kotlin that contains 2 fields userName and userPassword of type String .
Contains get() and set() methods that gets and sets the variables.
The get() method is annotated with @Bindable that specifies that particular field is Data Binded to a UI widget in layout.
Similar the set() sets notifyPropertyChanged(BR.userName) or notifyPropertyChanged(BR.userPassWord) that notifies the layout when the user entered values get changed .
The Data Class is as below :
package com.mvvm.kot.Kotlin_login_dataBinding.Model
import android.databinding.BaseObservable
import android.databinding.Bindable
import com.android.databinding.library.baseAdapters.BR
import com.google.gson.annotations.SerializedName
class LoginInfo : BaseObservable() {
var userName: String? = null
@Bindable get() = field
set(userName) {
field = userName
notifyPropertyChanged(BR.userName)
}
var userPassWord: String? = null
@Bindable get() = field
set(userPassWord) {
field = userPassWord
notifyPropertyChanged(BR.userPassWord)
}
}
Step 3: Data Binding in layout XML
The binding variables that can be used in expressions are defined inside a data
element that is a sibling of the UI layout's root element. Both elements are wrapped in a layout
tag as below:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data class="LoginFragmentBinding">
<variable
name="model"
type="com.mvvm.kot.Kotlin_login_dataBinding.Model.LoginInfo" />
<variable
name="viewModel"
type="com.mvvm.kot.Kotlin_login_dataBinding.ViewModels.LoginViewModel"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
>
<EditText
android:id="@+id/editTextemailID"
style="@style/Widget.AppCompat.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_margin="10dp"
android:hint="Email"
android:text="@={model.userName}"
/>
<EditText
android:id="@+id/editTextpassID"
style="@style/Widget.AppCompat.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_margin="10dp"
android:layout_below="@+id/editTextemailID"
android:hint="Password"
android:inputType="textWebPassword"
android:text="@={model.userPassWord}"
/>
<Button
android:id="@+id/loginbtn"
android:layout_below="@+id/editTextpassID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center"
android:layout_margin="10dp"
android:text="Login"
/>
</RelativeLayout>
</layout>
In the above layout we define variable as below:
<data class="LoginFragmentBinding">
<variable
name="model"
type="com.mvvm.kot.Kotlin_login_dataBinding.Model.LoginInfo" />
<variable
name="viewModel"
type="com.mvvm.kot.Kotlin_login_dataBinding.ViewModels.LoginViewModel"/>
We specify a class as an attribute to data tag in order to refer in activity
We specify a tag called variable with name “model” and in type we specify PoJO object which is LoginInfo.
Also we specify other variables that refers to ViewModel
We refer the model in EditText as below:
<EditText
android:id="@+id/editTextemailID"
style="@style/Widget.AppCompat.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_margin="10dp"
android:hint="Email"
android:text="@={model.userName}"
/>
<EditText
android:id="@+id/editTextpassID"
style="@style/Widget.AppCompat.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_margin="10dp"
android:layout_below="@+id/editTextemailID"
android:hint="Password"
android:inputType="textWebPassword"
android:text="@={model.userPassWord}"
/>
Step 4:
Inflating Data Binded layout in onCreateView() method of your fragment as below:
val loginBinder : LoginFragmentBinding = DataBindingUtil.inflate(inflater,R.layout.login_data_binding,container,false)
Step 5 : Return view from onCreateView() as below:
loginView = loginBinder.getRoot()
return loginView
Step 6: Fetching the user entered userName and userPassword from DataBinded Layout as below:
We use loginBinder to refer to widgets in layout without findViewByID
loginBinder.loginbtn.setOnClickListener(View.OnClickListener {
Log.d("LoginDatabinding",loginBinder.editTextemailID.getText().toString())
val email:String = loginBinder.editTextemailID.getText().toString()
val password:String = loginBinder.editTextpassID.text.toString()
loginViewModel.validateCredentials(email,password).observe(this,object: Observer<String> {
override fun onChanged(t: String?) {
Toast.makeText(activity, t, Toast.LENGTH_LONG).show()
}
})
})
The source code for basic Kotlin Login screen using MVVM with Data Binding is uploaded below: