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: