在某些情况下,我想要改变LiveData的值,但不希望观察者被通知到这一变化。我该如何做到这一点?
Pair<T, Boolean>
作为值类型,观察者可以检查pair.second
。MutableLiveData<Pair<String, Boolean>>
替换你的MutableLiveData<String>
。s
时,只需调用liveData.setValue(new Pair(s, true))
,否则调用liveData.setValue(new Pair(s, false))
。pair.second
以区分这两种情况。我认为我的自定义类会对你有所帮助
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.util.Pair;
import java.util.ArrayList;
import java.util.List;
public class SSBLiveData<T> extends MutableLiveData<T> {
private List<Pair<LifecycleOwner, Observer>> observers = new ArrayList<>();
@MainThread
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer observer) {
observers.add(new Pair<>(owner, observer));
super.observe(owner, observer);
}
@MainThread
private void resetAllObservers() {
for (Pair<LifecycleOwner, Observer> observer : observers) {
super.observe(observer.first, observer.second);
}
}
@MainThread
private void removeAllObservers() {
for (Pair<LifecycleOwner, Observer> observer : observers) {
removeObservers(observer.first);
}
}
@MainThread
void setValueWithoutNotify(T value) {
removeAllObservers();
super.setValue(value);
System.out.println("Not notifying value " + getValue());
}
// For androidx use this method
/*@MainThread
@Override
public void removeObserver(@NonNull Observer<? super T> observer) {
for (Pair<LifecycleOwner, Observer> observerItem : observers) {
if (observerItem.second.equals(observer) && observerItem.first.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
observers.remove(observerItem);
}
}
super.removeObserver(observer);
}*/
@MainThread
@Override
public void removeObserver(@NonNull Observer<T> observer) {
for (Pair<LifecycleOwner, Observer> observerItem : observers) {
if (observerItem.second.equals(observer) && observerItem.first.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
observers.remove(observerItem);
}
}
super.removeObserver(observer);
}
@Override
public void setValue(T value) {
super.setValue(value);
if (!hasObservers()) {
resetAllObservers();
}
}
}
使用方法如下:
SSBLiveData<String> liveData = new SSBLiveData<>();
liveData.setValueWithoutNotify("It won't get notified");
liveData.setValue("It will get notified");
SSBLiveData
实例,并且一个Activity
观察它。由于SSBLiveData
实例正在引用此Activity
的观察者,因此此Activity
将不会被垃圾回收。 - Sanlok Lee与被接受的答案中描述的相同的类,但在 Kotlin 中进行了重写,并使用了 AndroidX 导入:
import android.util.Pair
import androidx.annotation.MainThread
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.util.*
class ExtendedLiveData<T>() : MutableLiveData<T>() {
private val observers: MutableList<Pair<LifecycleOwner, Observer<in T>>> = ArrayList()
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
observers.add(Pair(owner, observer))
super.observe(owner, observer)
}
@MainThread
private fun resetAllObservers() {
for (observer in observers) {
super.observe(observer.first, observer.second)
}
}
@MainThread
private fun removeAllObservers() {
for (observer in observers) {
removeObservers(observer.first)
}
}
@MainThread
fun setValueWithoutNotify(value: T) {
removeAllObservers()
super.setValue(value)
println("Not notifying value " + getValue())
}
@MainThread
override fun removeObserver(observer: Observer<in T>) {
for (observerItem in observers) {
if (observerItem.second == observer && observerItem.first.lifecycle
.currentState == Lifecycle.State.DESTROYED
) {
observers.remove(observerItem)
}
}
super.removeObserver(observer)
}
override fun setValue(value: T) {
super.setValue(value)
if (!hasObservers()) {
resetAllObservers()
}
}
fun resetValue() {
super.setValue(null)
}
}