ArrayAdapter的notifyDataSetChanged方法是源码如下的:
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
mNotifyOnChange = true;
}
调用父类的notifyDataSetChanged方法,并且将一个属性设置为true。
mNotifyOnChange属性的说明是这样的:用来标识当数据源发生变化时,notifyDataSetChanged 方法是否必须被调用。该属性被广泛的用于ArrayAdapter对数据源进行修改的相应方法中,包括add、addAll、insert、remove、clear和sort方法。看一下其中add方法的源码:
public void add(T object) {
synchronized (mLock) {
if (mOriginalValues != null) {
mOriginalValues.add(object);
} else {
mObjects.add(object);
}
}
<span style="color:#FF0000;"> if (mNotifyOnChange)notifyDataSetChanged();</span>
}
当向数据源中添加了数据的时候,如果mNotifyOnChange为true,就调用ArrayAdapter的notifyDataSetChanged方法。
再回过头看ArrayAdapter的notifyDataSetChanged方法,它执行了父类的notifyDataSetChanged方法,也就是BaseAdapter的notifyDataSetChanged方法,看一下它的源码:
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
该方法的说明是:通知所有“注册”的观察者们,内部数据已经发生了变化,所有用来显示这些数据的视图都应该刷新一下自己显示新的数据。
显然这里用到了观察者模式,而mDataSetObservable从名字就可以看出来,它是观察者模式中的“主题”(Subject),也就是被观察者。BaseAdapter的notifyDataSetChanged实际就是调用了mDataSetObservable的notifyChanged方法。mDataSetObservable是BaseAdapter的一个属性:
private final DataSetObservable mDataSetObservable = new DataSetObservable();
该属性的类型为DataSetObservable,跟进去看一下这个类以及它的notifyChanged方法:
public class DataSetObservable extends Observable<DataSetObserver> {
public void <span style="color:#FF0000;">notifyChanged()</span> {
synchronized(mObservers) {
for (int i = mObservers.size() - 1;i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
public void notifyInvalidated() {
synchronized (mObservers) {
for (int i = mObservers.size() - 1;i >= 0; i--) {
mObservers.get(i).onInvalidated();
}
}
}
}
该类继承自Observable<T>,而Observable<T>是JDK中专门为观察者模式中的“主题”(Subject)也就是被观察者设计的一个类,这个类中包含了3个用来注册/注销观察者的方法,分别是:
registerObserver(T observer)
unregisterObserver(T observer)
unregisterAll()
这3个方法都是针对Observable<T>中一个用来“存储”观察者们的集合进行操作,这个集合是Observable<T>的一个属性:
protected final ArrayList<T> <span style="color:#FF0000;">mObservers</span> = new ArrayList<T>();
那么Observable<DataSetObserver>中的DataSetObserver又是什么类呢:
public abstract class DataSetObserver {
public void onChanged() {
}
public void onInvalidated() {
}
}
这是一个抽象类,它定义了两个空方法(但不是抽象方法)。关于这个类的说明主要包括两点:
1)当(被观察者内部的)数据集发生改变或不可用时用来接收回调。典型的数据集有像被观察的Cursor或者Adapter。
2)任何加入到DataSetObservable中的对象都必须是该类的实现类对象。
其中第2点的完整说法应该是加入到DataSetObservable的mObservers中的对象,都必须要继承DataSetObserver并应该重写其中的空方法。原因很简单,看一下DataSetObservable的notifyChanged方法就知道:
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1;i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
mObservers是DataSetObservable的父类Observable用来“存储”观察者们的集合。而DataSetObservable的notifyChanged方法实际就是在调用每一个观察者的(或者说DataSetObserver实现者)的onChanged方法。
OK,现在知道了ArrayAdapter的notifyDataSetChanged方法最终是触发了父类BaseAdapter的一个属性mDataSetObservable的notifyChanged方法,该方法会遍历mObservers中的每一个DataSetObserver,并调用它们的onChange方法。那么ArrayAdapter的mDataSetObservable是什么时候添加的DataSetObserver呢?是在ListView/GridView调用setAdapter方法的时候。看一下ListView的setAdapter方法:
publicvoid setAdapter(ListAdapter adapter) {
if (mAdapter != null &&mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();
if (mHeaderViewInfos.size() > 0||mFooterViewInfos.size() > 0) {
mAdapter = newHeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
}else {
mAdapter = adapter;
}
mOldSelectedPosition =INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
// AbsListView#setAdapter will updatechoice mode states.
super.setAdapter(adapter);
if (mAdapter != null) {
mAreAllItemsSelectable =mAdapter.areAllItemsEnabled();
mOldItemCount = mItemCount;
mItemCount = mAdapter.getCount();
checkFocus();
<span style="color:#FF0000;"> mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);</span>
mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());
int position;
if (mStackFromBottom) {
position = lookForSelectablePosition(mItemCount- 1, false);
} else {
position =lookForSelectablePosition(0, true);
}
setSelectedPositionInt(position);
setNextSelectedPositionInt(position);
if (mItemCount == 0) {
// Nothing selected
checkSelectionChanged();
}
} else {
mAreAllItemsSelectable = true;
checkFocus();
// Nothing selected
checkSelectionChanged();
}
<span style="color:#FF0000;"> requestLayout();</span>
}
可以看到里面有两行代码:
mDataSetObserver= new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
先看一下AdapterDataSetObserver类的内容:
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver{
@Override
public void onChanged() {
super.onChanged();
if (mFastScroller != null) {
mFastScroller.onSectionsChanged();
}
}
@Override
public void onInvalidated() {
super.onInvalidated();
if (mFastScroller != null) {
mFastScroller.onSectionsChanged();
}
}
}
它继承自AdapterView<ListAdapter>.AdapterDataSetObserver并且在onChanged和onInvalidated方法中均调用了父类的同名方法,因此再看一下AdapterView<ListAdapter>.AdapterDataSetObserver的内容:
class AdapterDataSetObserver<span style="color:#FF0000;"> extends DataSetObserver</span> {
private Parcelable mInstanceState =null;
@Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount =getAdapter().getCount();
// Detect the case where a cursorthat 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();
<span style="color:#FF0000;"> requestLayout();</span>
}
@Override
public void onInvalidated() {
//方法的具体实现略…
}
public void clearSavedState() {
mInstanceState = null;
}
}
AdapterView<ListAdapter>.AdapterDataSetObserver继承了DataSetObserver。这就说明mDataSetObserver是DataSetObserver的实现者,可以作为观察者被加入到mObservers中。所以接下来mAdapter.registerDataSetObserver(mDataSetObserver);就是将mDataSetObserver加入到mObervers中的。
看一下registerDataSetObserver方法的源码:
public void registerDataSetObserver(DataSetObserverobserver) {
mDataSetObservable.registerObserver(observer);
}
调用mDataSetObservable的registerObserver方法。DataSetObservable的registerObserver方法源码是:
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("Theobserver is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)){
throw newIllegalStateException("Observer " + observer + " is alreadyregistered.");
}
<span style="color:#FF0000;">mObservers.add(observer);</span>
}
}
所以mAdapter.registerDataSetObserver(mDataSetObserver)方法的作用就是将作为DataSetObserver实现者对象的mDataSetObserver添加到了mDataSetObservable的mObservers中。这样,当调用了ListView的setAdapter方法时,实际就是将作为方法参数传入的ArrayAdapter中的一个mDataSetObserver对象添加到了ArrayAdapter中的mDataSetObservable中的mObservers集合中,随着ArrayAdapter调用notifyDataSetChanged方法,就调用的是AdapterView<ListAdapter>.AdapterDataSetObserver重写的DataSetObserver中的onChanged方法。重写的onChanged方法的最后一句requestLayout会发起一个从顶层布局依次往下的重新布局,这个过程最终会调用到ListView的onLayout方法(ListView没有该方法,因此调用的是其父类的AbsListView的onLayout方法):
protected void onLayout(boolean changed, intl, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mInLayout = true;
if (changed) {
int childCount = getChildCount();
for (int i = 0; i < childCount;i++) {
getChildAt(i).forceLayout();
}
mRecycler.markChildrenDirty();
}
if (mFastScroller != null &&mItemCount != mOldItemCount) {
mFastScroller.onItemCountChanged(mOldItemCount, mItemCount);
}
<span style="color:#FF0000;">layoutChildren();</span>
mInLayout = false;
mOverscrollMax = (b - t) /OVERSCROLL_LIMIT_DIVISOR;
}
这里会触发layoutChildren方法,这个方法里会完成ListView彻底的布局重绘。源代码较长,就不粘贴了。