如何更改 LiveData 的值而不通知观察者

Mor*_*goo 2 android android-livedata

在某些情况下,我想更改 LiveData 的值并且不希望观察者通知更改。我怎样才能做到这一点?

ssy*_*htn 9

我只是Pair<T, Boolean>用作值类型,观察者可以检查pair.second

这个想法很简单。替换你MutableLiveData<String>MutableLiveData<Pair<String, Boolean>>

当你想用 value 通知观察者时s,只需调用liveData.setValue(new Pair(s, true))和调用liveData.setValue(new Pair(s, false))其他方式

在观察者方面,只需检查pair.second以区分这两种情况

编辑:我正在使用电话来回答这个问题,似乎 stackoverflow 隐藏了由尖括号包围的字符。


SSB*_*SSB 6

我想我的定制课程会对你有所帮助

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样使用

SSBLiveData<String> liveData = new SSBLiveData<>();
liveData.setValueWithoutNotify("It won't get notified");
liveData.setValue("It will get notified");
Run Code Online (Sandbox Code Playgroud)