How to Clear Livedata Stored Value

How to clear LiveData stored value?

Update

There are actually a few ways to resolve this issue. They are summarized nicely in the article LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case). This is written by a fellow Googler who works with the Architecture Components team.

TL;DR A more robust approach is to use an Event wrapper class, which you can see an example of at the bottom of the article.

This pattern has made it's way into numerous Android samples, for example:

  • Plaid
  • Architecture Blueprints
  • IOSched

Why is an Event wrapper preferred over SingleLiveEvent?

One issue with SingleLiveEvent is that if there are multiple observers to a SingleLiveEvent, only one of them will be notified when that data has changed - this can introduce subtle bugs and is hard to work around.

Using an Event wrapper class, all of your observers will be notified as normal. You can then choose to either explicitly "handle" the content (content is only "handled" once) or peek at the content, which always returns whatever the latest "content" was. In the dialog example, this means you can always see what the last message was with peek, but ensure that for every new message, the dialog only is triggered once, using getContentIfNotHandled.

Old Response

Alex's response in the comments is I think exactly what you're looking for. There's sample code for a class called SingleLiveEvent. The purpose of this class is described as:

A lifecycle-aware observable that sends only new updates after
subscription, used for events like navigation and Snackbar messages.

This avoids a common problem with events: on configuration change
(like rotation) an update can be emitted if the observer is active.
This LiveData only calls the observable if there's an explicit call to
setValue() or call().

Reset/clear viewmodel or livedata

but, aren't Viewmodels also aimed to share data between different views?

No. Each viewmodel should be responsible for one view. The "shared viewmodel" pattern is for cases when you have one large view (i.e., activity) that has multiple subviews (i.e., fragments) that need to share data / state, like the master / detail example in the documentation. It's a convenience for these cases when you need real-time updates amongst the subviews.

In your case, you're navigating between fragments and as such should be passing data through the transitions. This means passing arguments along when starting new fragments and registering for results when they complete their task.

Then each of your fragments is isolated, self-contained, more easily testable and you won't end up with a God-ViewModel that does All The Things™ and turns into a giant mess as you try to jump through hoops accounting for every state it could possibly be in.

How to use the LiveData value in another method of Activity?

Just use myViewModel.liveData.value to get the value.

Shouldn't liveData value be retrieved only through observer method?

Not only. When observing, you get notified when the value changes. Nothing prevents you from checking the value. LiveData is just a data holder.

LiveData prevent receive the last value when start observing

I`m using this EventWraper class from Google Samples inside MutableLiveData

/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
public class Event<T> {

private T mContent;

private boolean hasBeenHandled = false;


public Event( T content) {
if (content == null) {
throw new IllegalArgumentException("null values in Event are not allowed.");
}
mContent = content;
}

@Nullable
public T getContentIfNotHandled() {
if (hasBeenHandled) {
return null;
} else {
hasBeenHandled = true;
return mContent;
}
}

public boolean hasBeenHandled() {
return hasBeenHandled;
}
}

In ViewModel :

 /** expose Save LiveData Event */
public void newSaveEvent() {
saveEvent.setValue(new Event<>(true));
}

private final MutableLiveData<Event<Boolean>> saveEvent = new MutableLiveData<>();

public LiveData<Event<Boolean>> onSaveEvent() {
return saveEvent;
}

In Activity/Fragment

mViewModel
.onSaveEvent()
.observe(
getViewLifecycleOwner(),
booleanEvent -> {
if (booleanEvent != null)
final Boolean shouldSave = booleanEvent.getContentIfNotHandled();
if (shouldSave != null && shouldSave) saveData();
}
});


Related Topics



Leave a reply



Submit