While working with Recycler View in Android, we usually have to deal with various adapters specifically built for different lists. In someway, this has burdened us with more code to maintain. Therefore, I’ve created a common adapter that, together with data binding, can be used for any data set. This means you only have to create these classes once and reuse them multiple times.
- Build an adapter that can be reusable in many places.
- Encourage MVVM pattern so that models have all the logic and view is as dumb as possible.
This post assumes that you’re familiar with Android and it’s data binding feature. If you’re new to the concept, check out the official documents.
First, we need to provide necessary binding information so that the adapter knows what to display with the DataBindingEntry class:
This class contains the item’s layout id and a map of binding variables to be bound in that layout.
As the name infers, DataBindingViewHolder will do the binding “ritual” between view and data. This is the most important part of the whole approach, where everything can be abstract thanks to the power of data binding.
ViewDataBinding is the base class that every binding class generated by Android extends from. The reason why we don’t need a concrete implementation is because the base class has a method called setVariable that accepts any object. For concrete classes, you will have extra setters for variables you have declared in the layouts. When onBindViewHolder method in the adapter is called, a DataBindingEntry at a specific position will be passed in the holder’s bind method. Here we use the setVariable mentioned previously to bind all variables provided by the entry.
Some other implementations I see elsewhere also add viewBinding.executePendingBindings() method when binding the holder but I feel it unnecessary because setVariable() in generated classes already requests a rebind.
This class is the last piece of the puzzle, where all the things are wired up. The adapter will be responsible to create and bind the view holders as well as get the appropriate layout for the items.
Notice that onViewAttachedToWindow and onViewDetachedFromWindow methods within the adapter. Basically, they are called when a view holder becomes either visible or hidden. Thus, it’s a perfect place to invoke the DataBindingViewHolder’s life cycle functions.
Binding Adapter In Action
Now, whenever you show a list on the screen, these are the steps you need to do:
That’s it! That’s all you need to construct a list that can be utilised for any data set, even a complex one. The only job that the adapter has to do is setting the values to the correct view through bindings in the provided layout. Hence, all logic to determine how the data should be displayed is now contained the model, which I usually referred to as UI model. The different between a UI model and domain model is the fact that a UI model represents almost exactly what is shown on the particular screen, whereas a domain model represents the business logic throughout the application. For more detail, you can take look at this well-explained article.
This is a very basic implementation to show you how powerful data binding can be. Hopefully it helps. Happy coding :)