Explore Android MVVM-style

Android Data Binding Library is a support library that supports all Android platform versions back to Android 2.1 (API level 7+ ). It also requires Android Plugin for Gradle 1.5.0-alpha1 or higher.

Normally, Android UI has been done declaratively in XML layout files. But the XML layout contains no behavior. Behaviors still have to be in code that go in Activity or Fragment classes (and go to other classes but pretty much everything starts with OnCreate() in Activity or Fragment objects.

With data binding, we can organize and write the app in an MVVM-style. These are some of the benefits for writing in MVVM-style:

  1. Better separation of concern. Activity and Fragment classes are no longer needed to be made god objects. The method onCreate() can actually become much simpler as we shall see.
  2. Data binding allows for compile-time type safety that is otherwise missing by calling findViewById. findViewById also has to walk the view hierarchy so the more deeply nested hierarchy, the longer it would take for the app to find the element.
  3. Android Data Binding Library also supports 2-way binding, so with a ViewModel class that glues the View with the Model, changes can be initiated at either one, and be reflected on the other. No more clumsy code to do the refresh or update.

Here, I am putting together an app that has a Login page which consists of 2 EditText, a Button and a ProgressBar. We’ll explore writing this in MVVM-style.

First, in the file app/build.gradle, we enable data binding by simply doing the following:

Next, create a class called LoginViewModel

It’s fairly easy to guess. The LogonViewModel has 3 properties: email, password and busy and they are “observable fields”. The class also has a method called onClick() and we can guess this is the event handler for when the Login button is clicked on. In here I just simulate the asynchronous “login process”. As soon as the button is clicked, the busy property is set to View.VISIBLE. When login is done (simulated by 0.5 seconds delay), this busy property is set to View.GONE, and we display the email and password in a Snackbar. It’s reasonable to guess that this is the email and password that gets entered by the users.

It’s also possible to write the LoginViewModel class in another way as follow:

Now we can create a layout called activity_main.xml:

Let’s pause and see what’s new, i.e. related with Data Binding that are otherwise not seen:

(i)Everything is now wrapped inside an <layout> element.

(ii)The <data> element indicates there’s a variable called loginViewModel and its type is dev.kevinle.exploremvvm.LoginViewModel.

(iii) The handler is also set the same View Model class.

Also in this layout file, the new “things” are

This syntax @={..} indicates a 2-way binding while @{..} indicates a 1-way binding from the property in the View Model to the value that gets rendered in the View. As we can see, the email and password are 2-way data bound to the email and password properties in LoginViewModel respectively. The attribute android:visibility of the progress bar is “controlled” by the busy property in the View Model. We saw how it gets set to View.VISIBLE and View.GONE earlier. Finally, the onClick handler for the button is assigned to the android:onClick attribute.

If the build complains that @{handler.onClick} is deprecated, you can replace with @{handler::onClick}. But then it seems like Android Studio has a bug and put a red error mark near the double colon sign although this does not affect the build.

The onCreate() method of the Activity class now becomes really simple:

ActivityMainBinding is auto-generated by the Library. It takes the snake case name of the layout activity_main.xml, turns it into a camel case and append ‘Binding’ at the end, hence activity_main.xml -> ActivityMainBinding.

This sample shows that the Activity class now becomes really simple. I showed that the handlers now can reside in the View Model class, but it does not have to. The handlers can be in its own class or it can stay in the Activity class.

The point is now we can separate responsibilities. Personally, I think it makes sense to have the View Model class contains the handlers as well.

Finally, here’s the source.

Written by

Driven by passion and patience. Read my shorter posts https://dev.to/codeprototype (possibly duplicated from here but not always)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store