View actions (snackbar, activity navigation, ...) in ViewModel
See original GitHub issueSometimes the ViewModel needs to invoke an action using an Activity (for example to show a snack bar or to navigate to a new activity). Using MVP it’s easy to implement it because the presenter has a reference to the Activity. The ViewModel doesn’t contain a reference to the Activity, what’s the best way to implement this feature? In the GithubBrowserSample you created a method getErrorMessageIfNotHandled to solve this problem, are there other solutions? In a demo project I am working on I have created a UiActionsLiveData class that allows the ViewModel to invoke an action on the view. The connection between the ViewModel and the view is managed using a LiveData so the ViewModel doesn’t contain a reference to the View even if it can invoke actions on it. The usage is simple, the ViewModel can add an action to the UiActionsLiveData:
uiActions.execute { navigationController.showError(it, t.message) }
Thanks to the LiveData implementation the action will be executed on the Activity when it’s resumed. I like this solution but it’s a bit complicated, an official solution would be great.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:93
- Comments:84 (13 by maintainers)
Top GitHub Comments
We created something similar in Blueprints called
SingleLiveEvent
https://github.com/googlesamples/android-architecture/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/SingleLiveEvent.java
and another version called `SnackbarMessage’
https://github.com/googlesamples/android-architecture/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/SnackbarMessage.java
We’re thinking whether it should be part of the library.
Thoughts?
Edit: a blog post about events, SingleLiveEvent and a possibly better approach: https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
A big NO from my side for
SingleLiveEvent
! Unidirectional Dataflow and immutability ftw! (also a little state reducer over here and there doesn’t hurt)SearchViewModel
which offers aLiveData<LoadMoreState> getLoadMoreStatus()
method for the view to subscribe / listen to. So once the view has displayed the error message (i.e. with a snackbar) the View calls:This will then force the viewModel to emit a new (immutable) LoadMoreState.
behaves like
SingleLiveEvent
(i.e. after screen orientation change, snackbar wont show again, becauseLoadMoreState.errorMessage == null
) but is immutable!