Home » Android » android MVVM without Databinding

android MVVM without Databinding

Posted by: admin June 15, 2020 Leave a comment

Questions:

Question : Can I implement android app with MVVM without using Databinding.

Problem I am trying to solve is pretty simple:
read a list of items from backend API and show them in a Recylerview.

How I am implementing:

In the View – I have Activity and RecyclerViewAdapter
Model : ApiResponse and data models
network – retrofit API service, RxJava2

for ViewModel part – I have a ViewModel class(that doesn’t derive from anything) that basically calls Retrofit Service and gets data using RxJava calls.

ViewModel has calls such as :

 void getItems();
 void addItemData();
 void removeItem();

which call service with RXJava2 as

 ObServable<ApiResponse> getItems();
 ObServable<ApiResponse> addItemData();
 ObServable<ApiResponse> removeItem();  

View instantiates ViewModel object.
ViewModel gets the instance of Adapter object during creation.
In the View, clicking a button calls a ClickHandler in the Activity which calls a ViewModel#getItems() method. Since ViewModel has link to Adapter, the viewModel updates the items in the adapter so that RecyclerView is automatically updated.

I am not sure if this is right approach for MVVM.

Databinding seems a bit like spaghetti to me.

Again, can we implement MVVM in android without DataBinding ?
Is the approach OK?

How to&Answers:

Yes! You can. But i think your approach can be better.
Remember that the view model must not have a reference to your view.
ViewModel expose observables, and in your view, you should observe those observables and react over changes.
You can have something like this:

Note: This example is with Kotlin and LiveData because, why not? But you can take this and use it with Java & Rx

ItemsViewModel : ViewModel() {
  private val items = MutableLiveData<List<Items>>()

  fun getAllItems() : LiveData<List<Items>> {
      return items
    }

   //..
}

ItemsActivity : Activity() {
  private var itemsAdapter: ItemsAdapter? = null
  private var viewModel: ItemsViewModel? = null

  override fun onCreate(savedInstance: Bundle) {
  // ...

   // Create your Adapter
   itemsAdapter = ItemsAdapter()
   recyclerView.adapter = itemsAdapter

   // Create and observe your view model
   viewModel =  ViewModelProviders.of(this).get(ItemsViewModel::class.java)

   viewModel.getAllItems().observe(this, Observer {
      it?.let {
          adapter?.datasource = it
      }
}

In this case, the view observes view model, and notify the adapter. Then in your adapter, you do the bind as usual, without databinding.

Answer:

Definitely possible, it’s totally up to you how you interpret the “binding” part of MVVM. In our team, we use MVVM with RxJava instead of Android Data Binding.
Your ViewModel has an interface with outputs and inputs like this:

interface TasksViewModel {
        // inputs
        Observer<Task> taskAddedTrigger();
        Observer<Task> taskClickedTrigger();
        Observer<Task> taskCompletedTrigger();

        // outputs   
        Observable<Boolean> isLoading();
        Observable<List<Task>> tasks();
}

Your ViewModel then just uses RxJava to map inputs to outputs in a very functional style.
You Fragment supplies Inputs to the ViewModel whenever User input is received. It subscribes to Outputs and updates the user interface accordingly when the ViewModel’s Output changes.
Here is a blog post which covers the topic in detail (Disclaimer: I wrote it)

Answer:

The distinguishing characteristic of MVVM is that the ViewModel is not directly coupled to a View (indeed, you could bind your ViewModel to different layouts). This also has implications on the ease of unit testing. By having a reference to the Adapter, it is technically more like MVC. You don’t have to use databinding, but for true MVVM, I think you would need another Observer Pattern mechanism for the View to be notified of changes so that it could pull the data it needs.

Answer:

Your saying Since ViewModel has a link to Adapter and that is the problem because ViewModel should not have reference to view and In your adapter, you have views so by doing this your not following MVVM at all!!

You can still use MVVM without data binding but you need some way to notify the view about data changes, It can be LiveData (preferred way), Java Observable, Rx or even a custom implementation. The view will get notified about the changes and updates itself, in your case, view will update the adapter.

see my answer here for an example Are actions allowed in MVVM? Android

Answer:

I think you should use data binding to notify the data changed from network or database, your viewmodel should expose methods for requiring or updating data, when the data arrived you can do some operation on your data, and post them to your container(activity or fragment), in there you can update your RecyclerView and its adapter