Skip to content

写了个简版的防止倒灌,不知道行不行 #17

Open
@RebornWolfman

Description

public class EventMutableLiveData extends LiveData {

private final AtomicInteger currentVersion = new AtomicInteger(-1);

/**
 * 这个标志主要是是否忽略最新值, observe(@NonNull @NotNull LifecycleOwner owner, @NonNull @NotNull Observer<? super T> observer) 才会生效
 * 比如从页面1 来到页面2 页面2 再回到页面1 页面1默认是会收到页面2 最新的值,不想收到这个值可以设置为true
 */
private boolean isIgnoreLastObserve;

private final HashMap<Observer<? super T>, ObserverProxy> observerMap = new HashMap<>();

public EventMutableLiveData(boolean isIgnoreLastObserve) {
    super();
    this.isIgnoreLastObserve = isIgnoreLastObserve;
}

public EventMutableLiveData() {
    super();
}

@Override
public void observe(@NonNull @NotNull LifecycleOwner owner, @NonNull @NotNull Observer<? super T> observer) {
    if (!observerMap.containsKey(observer)) {
        observerMap.put(observer, new ObserverProxy(observer, currentVersion.get(), false));
    } else {
        Objects.requireNonNull(observerMap.get(observer)).changeVersion(currentVersion.get());
    }
    super.observe(owner, Objects.requireNonNull(observerMap.get(observer)));
}

@Override
public void observeForever(@NonNull @NotNull Observer<? super T> observer) {
    if (!observerMap.containsKey(observer)) {
        observerMap.put(observer, new ObserverProxy(observer, currentVersion.get(), true));
    }
    super.observeForever(Objects.requireNonNull(observerMap.get(observer)));
}

@Override
public void setValue(T value) {
    currentVersion.getAndIncrement();
    super.setValue(value);
}

@Override
public void postValue(T value) {
    currentVersion.getAndIncrement();
    super.postValue(value);
}

class ObserverProxy implements Observer<T> {

    private final Observer<? super T> observer;

    private int mVersion = -1;

    private final boolean isForever;

    public ObserverProxy(@NotNull Observer<? super T> observer, int mVersion, boolean isForever) {
        this.observer = observer;
        this.mVersion = mVersion;
        this.isForever = isForever;
    }

    @Override
    public synchronized void onChanged(T t) {
        if (currentVersion.get() > mVersion) {
            observer.onChanged(t);
            if (isIgnoreLastObserve && !isForever) {
                Set<Map.Entry<Observer<? super T>, ObserverProxy>> set = observerMap.entrySet();
                for (Map.Entry<Observer<? super T>, ObserverProxy> item : set) {
                    item.getValue().changeVersion(currentVersion.get());
                }
            }
        }
    }

    private void changeVersion(int newVersion) {
        this.mVersion = newVersion;
    }
}

@Override
public void removeObserver(@NonNull @NotNull Observer<? super T> observer) {
    super.removeObserver(observer);
    observerMap.remove(observer);
}

public void removeAllObserver() {
    Set<Map.Entry<Observer<? super T>, ObserverProxy>> set = observerMap.entrySet();
    for (Map.Entry<Observer<? super T>, ObserverProxy> item : set) {
        super.removeObserver(item.getValue());
    }
    observerMap.clear();
}

}

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions