Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data between Activity and ViewModel

Tags:

android

mvvm

I'm learning the new Architecture Components for Android programming and I'm having a tough time understanding what the responsibilities for an activity are. I get that they are only supposed to handle UI, which makes sense, but to what extent? Let's say I have an activity where, initially, there's an EditText where the user can enter a String. There's a button below this that adds another EditText for the user to enter another String. How should this data be handled behind the scenes? The two solutions I've come up with are the following:

1) Handle the data in the ViewModel.

User clicks the button -> Activity tells ViewModel -> ViewModel maintains list of EditTexts -> When user is done, Activity tells ViewModel -> ViewModel processes data

The issue I see with this approach is that now there are UI elements in the ViewModel and I would have to handle a state of sorts (The user adds some EditTexts but then cancels the whole operation and the ViewModel would have to clear it's list)

2) Handle the data in the Activity.

User clicks the button -> Activity maintains list of EditTexts -> When user is done, Activity sends list of Strings to ViewModel -> ViewModel processes data

The issue I see with this approach is that now there's logic in the View that would have to be replaced if this View was ever replaced, it's not as "dumb" as it should be.

what's the preferred way of handling this situation?

like image 469
user2929779 Avatar asked Aug 05 '18 18:08

user2929779


People also ask

Can ViewModel be share between activities?

In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.

How do you pass data between activities?

This example demonstrates how do I pass data between activities in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.

How do you pass data between fragments using ViewModel?

Sharing data between fragments is super easy if you use Navigation Architecture Component in your project. In the Navigation component, you can initialize a ViewModel with a navigation graph scope. This means all the fragments in the same navigation graph and their parent Activity share the same ViewModel.


1 Answers

First of a ViewModel should never include a View such as EditText, as quouted from the ViewModel page: "Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.". When you do, it might cause a memory-leak so that excludes option 1.

Secondly the ViewModel shouldn't be used for processing data, it is merely a container for the data. Processing should be preformed in the background and the result should be stored in the ViewModel, so that potential listeners can react to the data-change.

So to answer you question: In this case I would create a custom ListView with a custom view that contains a EditText. Our ViewModel will contain MutableLiveData for a String list called entries, like this MutableLiveData<List<String>> entries = new MutableLiveData<List<String>>(); which we can set by calling the setValue(object) method.

When the user pushes the button all the text from the EditText views are combined in a String list and we set entries to the created list with the setValue(object) method. All the listeners to entries, will be providen with the new data. So for example you could kick off a background job for processing the new values, like so: model.entries.observe(this, Observer { ProcessStringListTask().execute(it) }) (note that the code is in Kotlin).

Hopes this answers your question.

Best regards,

Dingenis

like image 72
Bram Sinke Avatar answered Oct 06 '22 01:10

Bram Sinke