Category Archives: MVVM Android

Data Binding (MVVM) I/O 2016

Hello Guys,
I am gonna tell you about few things of data binding. These are :

1) What is data binding ?
2) Why Should We use it ?
3) How to use it ? (And about MVVM).
4) Event Handling.
5) How Data Binding works (Behind the Scene) ?
6) Two Way Data Binding.
7) Binding with Recyclerview.
8) Data Binding Example.
9) Custom Binders.
10) Advantages and Disadvantages of Data Binding.
11) References.

So here we begin,

1) What is Data Binding :

Data binding is the process that establishes a connection between the application UI and business logic. If the binding has the correct settings and the data provides the proper notifications, then, when the data changes its value, the elements that are bound to the data reflect changes automatically.
Data binding can also mean that if an outer representation of the data in an element changes, then the underlying data can be automatically updated to reflect the change.
For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.

2) Why Should We Use It :

  1. Easy to handle and code.
  2. Removal of unnecessary relevant code (like Expression chaining).
  3. Removal finding viewById and setting listeners.
  4. And the most powerful feature Two-way data binding.
  5. Handling of Null Pointer Exception.

 

3) How to use It :

We will be using in MVVM (Model-View-ViewModel) pattern. As its been recommended by Google Android Team, to use each layer separately, so that our business logic does not get involved with our view.

For example, like to fetch contacts in Activity we make use of Cursor Loader in Activity/Fragment. But what if we have to test the logic part of cursor loader separately.
So for this purpose we then have to temporarily comment or remove extra code and then run test cases.

So in all, it becomes quite messy and unwanted work load.
Therefore, we should keep maintaining business logic and view layer completely different, also to interact in between these two layers we should use ViewModel layer.

Requirement :
1) Android 2.1
2) Android Plugin for Gradle 1.5.0-alpha1 or higher.


In project gradle :

android {

….

dataBinding{

enabled = true

}

}

 

Starting with first layout file :

Just keep :
<layout> as your root view and with sub tags <data></data> and any viewgroup.
Please make sure it will not work with <merge> tags. We have to specify at least one viewgroup.

Example :
<layout xmlns:android=”http…”>
<data>
<variable name=”user” type=”com.example…User/>
</data>
<LinearLayout
width=”match_parent”
height=”match_parent”>

<Textview width=”wrap_content”
height=”wrap_content”
text=”@{user.firstName}”/>

<Textview width=”wrap_content”
height=”wrap_content”
text=”@{user.lastName}”/>
</LinearLayout>
</layout>

Please Note : @{} denotes data bound value, which is going to get bind with object.

 

User Object (Model, This will be part of Model layer) 

public class User{
public final String firstName;
public final String lastName;

public User(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}

}

Now when we called text=”@{user.firstName}”, it will generate getter for this variable at compile time only and set its value.

 

MainActivity (View layer) :

public void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
MainActivityBinding binding = DataBindingUtil.setContentView(this,R.layout.main_activity);
User user = new User(“Test”,”User”);
binding.setUser(user);
}

 

Now here, DataBindingUtil is default class from Android.
MainActivityBinding is created automatically when we create layout file with <layout> as root tag.
It can be used to bind the Object and to get any variable (if required).
binding.setUser(user), it binds the object values (the variable which we mentioned in xml layout file).
Its much important as without it, the xml will not get values.

 

Please Note :  If the user object is null or any of its value is null then also data binding will handle it without app getting crash.
binding.setUser(null) -> it will still work.

 

4) Event Handling :

Event Handling is setting click events on view components.
It can be done in two ways :

1) Method Reference:
The expression is processed at compile time. Data binding wraps a listener on the target view.
It can be any onClick, onLongClick or any other custom attribute also.
Example : android:onClick=”@{variable.onButtonClick}”
Or if it’s in same activity then android:onClick=”onButtonClick”


2) Listener Binding:
It is used with lambda expression.This expression is evaluated when actual event happens.
Like if based on certain object value you have show/hide values or make it of different color then you must use this handling. Also it’s used to pass parameters for any methods also.
Example : android:onClick=”@{() -> variable.onButtonClick()}”
android:onClick=”@{(v) -> v.isVisible() ? doSomething() : void}”

 

5) Now what actually happens behind the scene :

1) Application begins with compilation.

2) First it process layout files, (over here whatever data binding expressions are written it gets deleted) and passed for further implementation.

3) Now these expressions are parsed first, means the syntax of data binding you have specified. If it’s wrong it will through you the error else it will continue with next step.

4) Now it comes to java code, the part of code which we used in our expressions. (like user.isFriend). And check whether it’s grammatically correct or wrong.

5) Now its corresponding setter/getter is called (like user.name, etc).

6) Two way data binding :

Data Binding is not only up to binding of data with UI, but also to update UI values when object value changes.
Here comes the actual/real power of data binding that is Two-Way Data Binding.
It can be used by giving your data objects the ability to notify when data changes.

We can implement Two way binding by using the following three ways :

1) Observable Object.

For this we have to extend BaseObservable class and call notifyPropertyChanged(BR.variableName) in setter of variable. Also we have to use annotation @Bindable in getters.
BR is also a class file like ‘R’, which is having ids of all variables.

2) Observable Fields.

The above method is bit time consuming. So we can use in this way also:
ObservableField<String> firstName = new ObservableField<String>();
user.firstName.set(“Sunny”);
It will change the object value and UI also.

3) Observable Collections.
This is must to use if we are using data binding on Recylerview or listview as our views get reused, so we cannot use simple array list, map, etc.


7) Binding with Recyclerview :

Data Binding has really reduced our efforts, just check it out (Adapter) :

With Data Binding :
public static class BindingHolder extends RecyclerView.ViewHolder {

    private ViewDataBinding binding;
     public BindingHolder(View rowView) {
super(rowView);
 binding = DataBindingUtil.bind(rowView);
     }
   public ViewDataBinding getBinding() {
 return binding;
     }
}

Without Data Binding :

public static class ViewHolder extends RecyclerView.ViewHolder {
  private TextView title, author, publisher;
    private ImageView thumbnail;
       public ViewHolder(View v) {
         super(v);
         title = (TextView) v.findViewById(R.id.book_title_textview);
          author = (TextView) v.findViewById(R.id.book_authors_textview);
          publisher = (TextView) v.findViewById(R.id.book_publisher_textview);
          thumbnail = (ImageView) v.findViewById(R.id.book_thumbnail_imageview);
     }
  }

 

With Data Binding :

@Override
  public void onBindViewHolder(BindingHolder holder, int position) {
     final Book book = mBooks.get(position);
     holder.getBinding().setVariable(BR.book, book);
   //To make happen binding immediately! (At times binding get scheduled, so to make it         happen forcefully and immediately)
     holder.getBinding().executePendingBindings();
  }

Without Data Binding :

@Override
  public void onBindViewHolder(ViewHolder holder, int position) {
     final Book book = mBooks.get(position);
     holder.author.setText(book.author);
     holder.title.setText(book.title);
     holder.publisher.setText(book.publisher);
}

@Override
  public BindingHolder onCreateViewHolder(ViewGroup parent, int type) {
     View v = LayoutInflater.from(parent.getContext())  .inflate(R.layout.row_search_result, parent, false);
     BindingHolder holder = new BindingHolder(v);
     return holder;
  }

 

8) Example :
Whatever we have seen, please find its working example of Data Binding with Activity and Fragment (with recyclerview, click events both method reference and listener binding, data passing via methods, custom font, etc.) at following location :

https://github.com/Sunny1989/DataBindingExample

Please download and run in Android Studio.

 

9) Custom Binders :

It can be used to bind :
 1) Custom Fonts.
 2) View Layout.
 3) Vector Drawables.

For Custom font we have used in current example, I will post another example with vector drawables also soon.

10) Pros and Cons with Data Binding :

Pros :
1) Although it makes Activities and Fragment light.
2) Also we can unit test view-model (business logic) without view bind to it. (MVVM)

But still few difficulties persists (Cons):
1) No proper/ specific error reporting for data binding.
2) Not much blogs maintained yet. (2015 blogs are outdated, just for understanding).

 

11) References :

  1. https://developer.android.com/topic/libraries/data-binding/index.html
  2. http://mutualmobile.com/posts/using-data-binding-api-in-recyclerview
  3. https://labs.ribot.co.uk/approaching-android-with-mvvm-8ceec02d5442#.ghtzbdgo5
  4. https://github.com/radzio/android-data-binding-recyclerview (this example is having multiple views for same recylerview).
  5. https://realm.io/news/data-binding-android-boyar-mount/
  6. And please do watch Google I/O 16 for Data Binding.

    Also I have personally taken help from George Mount to reach up to this level.

    https://plus.google.com/+GeorgeMount007

    You can refer to his blogs also (Half thought).

Thanks for reading it out, please do let me know if I can be helpful for you.