ListView adapter notifyDataSetChanged() track

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);
......................................................
}


BaseAdapter:

    下面的操作全部委托给mDataSetObservable了:
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }

    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }

    而 private final DataSetObservable mDataSetObservable = new DataSetObservable();


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)的方式.

你可能感兴趣的:(android)