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
Android, How to Create Option Menu
Bring Application to Front After User Clicks on Home Button
Touch and Drag Image in Android
Changing Default Port (I.E. 5037) on Which Adb Server Runs
How to Programmatically Get the List of Registered Users in Firebase
Navigation Drawer with Backword Compatibility Android
Android How to Implement Bottom Sheet from Material Design Docs
Bulk Insertion on Android Device
Send Touch Events to a Device via Adb
Play Sound Using Soundpool Example
Image Size for All Screen Devices
Rotate an Yuv Byte Array on Android
How to Set Alarm in Android Programmatically
Android Saf (Storage Access Framework): Get Particular File Uri from Treeuri
Jpeg Images Have Different Pixel Values Across Multiple Devices
Buttons Not Visible on the Application. What's Wrong
Differencebetween System Apps and Privileged Apps on Android