Livedata Prevent Receive the Last Value When Start Observing

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();
}
});

Live data giving old value again while changing fragment

Using SingleLiveEvent class instead of LiveData in OnBoardViewModel class will solve your problem:

val signInResponse: SingleLiveEvent <APIResource<SignInResponse>>.

class SingleLiveEvent<T> : MutableLiveData<T>() {

private val pending = AtomicBoolean(false)

override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, Observer<T> { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}

override fun setValue(t: T?) {
pending.set(true)
super.setValue(t)
}

fun call() {
postValue(null)
}

}

This is a lifecycle-aware observable that sends only new updates after subscription. This LiveData only calls the observable if there's an explicit call to setValue() or call().

LiveData Observer triggers when not needed

There is a popular answer for this. You can wrap your StateInfo with SingleEvent class:

open class SingleEvent<out T>(private val content: T) {

var hasBeenHandled = false
private set // Allow external read but not write

/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}

/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}

So your observer looks like below:

private val syncStateObserver = Observer<SingleEvent<StateInfo>> {
it.getContentIfNotHandled()?: return@Observer

when (it.peek()) {
is Guest -> doWhenUserIsGuest()
is Authorized -> doWhenUserIsAuthorized()
}
}

MutableLivedata observer triggers only value is changed

This is happening because you are using distinctUntilChanged(). Try like below.

val text : LiveData<String>
get() = _text

Cannot Obeserve LiveData

Changing

private val communicationViewModel by lazy {
ViewModelProvider(this).get(
MyProfileEditSharedViewModel::class.java
)
}

to

private val communicationViewModel by lazy {
ViewModelProvider(requireActivity()).get(
MyProfileEditSharedViewModel::class.java
)
}

Solved the problem.
The official docs told me to change this to requireActivity()



Related Topics



Leave a reply



Submit