ViewModel : UI-Related Data Object

One of the biggest challenges for an Android developer is keeping data across configuration changes such as screen rotation or during the recreation of Activity/Fragments after it's been destroyed and recreated by the framework. Luckily the new Android Architecture Components library has ViewModel class that is intended to store and manage UI-related data so that the data survives configuration changes.

hero

Benefits

  • Keeps data across UI recreation
  • No need to repeat API calls and Database queries on UI recreation
  • Keeps Activity/Fragments clean since work is now delegated to ViewModels
  • Share ViewModels between Fragments

Subclass ViewModel

public class TimerViewModel extends ViewModel {
    private TimerLiveData timerLiveData;
    public TimerLiveData getTimer(){
        if(timerLiveData == null)
            timerLiveData = new TimerLiveData();
        return timerLiveData;
    }
}

To create a view-model just subclass ViewModel. View-models are responsible to provide data and keep reference to it. Our TimerViewModel lazily initializes TimerLiveData which is a LiveData implementation of a timer that counts seconds, read more about TimerLiveData and what exactly LiveData is used for in my post here.

Access And Observe

public class HomeActivity extends AppCompatActivity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        textView = findViewById(R.id.textView);
        TimerViewModel timerViewModel = ViewModelProviders.of(this).get(TimerViewModel.class);
        timerViewModel.getTimer().observe(this, integer -> textView.setText("Counter Time: " + integer + "s"));
    }
}

Now the Activity (or Fragments) can access this view-model via ViewModelProviders.of() function that takes Activity or Function that will become the owner of the view-model. Because our TimerLiveData is an observable, we can subscribe for value changes (that happen every second) and then update text view. To share a view-model between Fragments use getActivity() in ViewModelProviders.of() to get view-model owned by the parent Activity.

Results

results

Sources and further reading: