ListView 为了方便使用,自己在setAdapter()的时候就会register 一个新的AdapterDataSetObserver,以响应之后的adapter的notifyDataSetChanged(),本质就是一个观察者模式的实现:
@Override public void setAdapter(ListAdapter adapter) { if (mAdapter != null && mDataSetObserver != null) { mAdapter.unregisterDataSetObserver(mDataSetObserver); } .................................................. super.setAdapter(adapter); if (mAdapter != null) { mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); checkFocus(); mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); ...................................................... }
下面的操作全部委托给mDataSetObservable了: public void registerDataSetObserver(DataSetObserver observer) { mDataSetObservable.registerObserver(observer); } public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); } 而 private final DataSetObservable mDataSetObservable = new DataSetObservable();
public void notifyChanged() { synchronized(mObservers) { // since onChanged() is implemented by the app, it could do anything, including // removing itself from {@link mObservers} - and that could cause problems if // an iterator is used on the ArrayList {@link mObservers}. // to avoid such problems, just march thru the list in the reverse order. for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } }挨个调用在自己这里注册的Observer的onChanged(),
那么对于ListView, 就一定会调用ListView自己register的AdapterDataSetObserver,
AdapterDataSetObserver定义在AbsListView中,是ListView的父类,
而 AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver:
class AdapterDataSetObserver extends DataSetObserver { private Parcelable mInstanceState = null; @Override public void onChanged() { mDataChanged = true; mOldItemCount = mItemCount; mItemCount = getAdapter().getCount(); // Detect the case where a cursor that was previously invalidated has // been repopulated with new data. if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null && mOldItemCount == 0 && mItemCount > 0) { AdapterView.this.onRestoreInstanceState(mInstanceState); mInstanceState = null; } else { rememberSyncState(); } checkFocus(); requestLayout(); } ................................................................ }可以看到,notifyDataSetChanged()最重要的是调用到了AdaperView(其实这里是ListView)的requestLayout,
这样就在这一次出发的layout()(onLayout())里,就可以更新要显示的数据和View了。
ListView是自己直接为自己register了一个DataSetObserver, 但是AdapterView自己是不会配的,用的话,要自己register一个,
这也符合子类(ListView)扩展父类(AdapterView)的方式.