recyclerview的观察者模式

众所都知:recyclerview的显示ui步骤是先setAdapter,然后改变数据时调用notifyDataSetChanged()方法

1.先看recyclerview的setAdapter()方法

public void setAdapter(@Nullable Adapter adapter) {
        // bail out if layout is frozen
        setLayoutFrozen(false);
        setAdapterInternal(adapter, false, true);
        processDataSetCompletelyChanged(false);
        requestLayout();
    }

2.里面有 setAdapterInternal(adapter, false, true);

private void setAdapterInternal(@Nullable Adapter adapter, boolean compatibleWithPrevious,
            boolean removeAndRecycleViews) {
        if (mAdapter != null) {
            mAdapter.unregisterAdapterDataObserver(mObserver);
            mAdapter.onDetachedFromRecyclerView(this);
        }
       ...
        final Adapter oldAdapter = mAdapter;
        mAdapter = adapter;
        if (adapter != null) {
            adapter.registerAdapterDataObserver(mObserver); //注册观察者
            adapter.onAttachedToRecyclerView(this);
        }
      ...
    }
  1. adapter.registerAdapterDataObserver(mObserver);里的mObserver,我们跟踪源码发现mObserver是recyclerview的成员:
 private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();

那我们直接看RecyclerViewDataObserver这个类

//观察者实现类
private class RecyclerViewDataObserver extends AdapterDataObserver {
        RecyclerViewDataObserver() {
        }

        @Override
        public void onChanged() {
            assertNotInLayoutOrScroll(null);
            mState.mStructureChanged = true;

            processDataSetCompletelyChanged(true);
            if (!mAdapterHelper.hasPendingUpdates()) {
                requestLayout();
            }
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
           ...
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            ...
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
             ...
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            ...
        }
            ...
    }

4.跟踪源码发现RecyclerViewDataObserver 是继承抽象类AdapterDataObserver ,就是个观察者类

//观察者抽象类
public abstract static class AdapterDataObserver {
        public void onChanged() {
            // Do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
            // fallback to onItemRangeChanged(positionStart, itemCount) if app
            // does not override this method.
            onItemRangeChanged(positionStart, itemCount);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            // do nothing
        }
    }

5.到了这步我们回过头去看adapter.registerAdapterDataObserver(mObserver); 里面做了什么

public abstract static class Adapter {
        private final AdapterDataObservable mObservable = new AdapterDataObservable();
        ...
        public void registerAdapterDataObserver(@NonNull AdapterDataObserver observer) {
            //把观察者对象加入到观察者集合
            mObservable.registerObserver(observer);
        }

}

//被观察者抽象类
public abstract class Observable {

    //定义一个接收观察者对象的集合
    protected final ArrayList mObservers = new ArrayList();

    //把观察者对象传入添加进这个观察者集合
    public void registerObserver(T observer) {
        if (observer == null) {
            throw new IllegalArgumentException("The observer is null.");
        }
        synchronized(mObservers) {
            if (mObservers.contains(observer)) {
                throw new IllegalStateException("Observer " + observer + " is already registered.");
            }
            mObservers.add(observer);
        }
    }
}

//被观察者的实现类
static class AdapterDataObservable extends Observable {
        public boolean hasObservers() {
            return !mObservers.isEmpty();
        }

       //adapter.notifyDataSetChanged()时调到这里
        public void notifyChanged() {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                //遍历观察者集合,最后调入到RecyclerViewDataObserver 这个观察者实现类的onChanged()
                mObservers.get(i).onChanged();
            }
        }

        public void notifyItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(positionStart, itemCount, null);
        }

        public void notifyItemRangeChanged(int positionStart, int itemCount,
                @Nullable Object payload) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
            }
        }

        public void notifyItemRangeInserted(int positionStart, int itemCount) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeInserted(positionStart, itemCount);
            }
        }

        public void notifyItemRangeRemoved(int positionStart, int itemCount) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
            }
        }

        public void notifyItemMoved(int fromPosition, int toPosition) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);
            }
        }
    }

6.最后看adapter.notifyDataSetChanged();就是调用mObservable.notifyChanged();也就是调到第五步的被观察者AdapterDataObservable的notifyChanged()方法,也就调用到了RecyclerViewDataObserver 的onChanged()方法去做刷新ui的操作

public abstract static class Adapter {
        private final AdapterDataObservable mObservable = new AdapterDataObservable();
        ...
        public final void notifyDataSetChanged() {
            mObservable.notifyChanged();
        }

}

你可能感兴趣的:(recyclerview的观察者模式)