众所都知: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);
}
...
}
- 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();
}
}