Nicolas Jafelle
Nicolas Jafelle

Reputation: 2771

Android Arch Components ViewModel and LiveData trigger after screen rotation

I have a problem when using ViewModel and LiveData arch components. When using fragments and rotating the screen, the observer gets triggered...

I tried to move viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) in all the fragment lifecycle methods, but with no success.

My scenario is relatively straightforward:

  1. Login screen with email and password
  2. User clicks on the "login" button
  3. The viewmodel calls the login(email, password) and sets the value of the LiveData object
  4. Just for now simply show a Toast

At this point everything is okay. But when I rotate the screen the Toast appears again without any user interaction.

Do I have to do something in onDestroyView() ?

Thanks in advance!

Upvotes: 19

Views: 6220

Answers (2)

Nicolas Jafelle
Nicolas Jafelle

Reputation: 2771

Ok Finally found the problem and how to solve. LiveData is not designed for single events. For that reason there is a couple of ways to fix it or handle it, this two links were useful for me:

Jose Alcérreca's post dealing with this problem

Jose Alcérreca's EventObserver

Jose Alcérreca's SingleLiveEvent class

Basically:

In ViewModel:

var eventLiveData: MutableLiveData<Event<ErrorResponse>> = MutableLiveData()

and In Activity or Fragment:

viewModel.eventLiveData.observe(this, EventObserver {
     it?.let {
          shortToast(it.message)
     }
})

Upvotes: 15

Thracian
Thracian

Reputation: 67149

It's how LiveData and ViewModel works. You are getting same ViewModel with same LiveData and LiveData has previous object, User for instance, with previous credentials when you call ViewModelProviders.of(this).get(MainViewModel::class.java). You can reset User of LiveData onPause()or onStop() to reset it to initial state.

I don't know how you call toast, if you can share your ViewModel and MainActivity i can be more specific.

Upvotes: 5

Related Questions