一直以来Adapter的使用都只是流于表面,只知道要实现几个抽象的方法,把Adapter设置给某种listView,就可以很好的工作起来。所谓理解只是建立在主观的猜想上面,觉得应该是这样,对,ok,就这样,恩, 明白了。但是事实上却没有正真的懂它。这可以说Android的设计模式真的做得很好,无需了解实现就可以很好的运用,不过总感觉没有深入的追究还是少了点什么。那就看看它的一些细节吧。尤其来看看我一直疑惑的为什么调用notifyDataSetChanged notifyDataSetInvalidated 就可以重绘View。
首先还是从我掌握的有限的线索开始,notifyDataSetChanged 方法是怎么实现的呢?
根据经验发现,几乎我们用到的Adapter都是继承自BaseAdapter,借助eclipse 的Type Hierarchy View 也可以确认确实是这么回事,ok,那看看它的实现:
/**
* Notifies the attached observers that the underlying data has been changed
* and any View reflecting the data set should refresh itself.
*/
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
/**
* Notifies the attached observers that the underlying data is no longer valid
* or available. Once invoked this adapter is no longer valid and should
* not report further data set changes.
*/
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
原来是个Observer的实现,这个倒是和我之前的猜想差不多。
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实现发现时个abstract的,怎么办,到底是谁呢?看来要找个具体的实现。看看比较熟悉的ListView
和比较熟悉的ListAdapter,在ListView的setAdapter里发现
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
AdapterDataSetObserver的实现在AdapterView:
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();
}
@Override
public void onInvalidated() {
mDataChanged = true;
if (AdapterView.this.getAdapter().hasStableIds()) {
// Remember the current state for the case where our hosting activity is being
// stopped and later restarted
mInstanceState = AdapterView.this.onSaveInstanceState();
}
// Data is invalid so we should reset our state
mOldItemCount = mItemCount;
mItemCount = 0;
mSelectedPosition = INVALID_POSITION;
mSelectedRowId = INVALID_ROW_ID;
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
checkFocus();
requestLayout();
}
public void clearSavedState() {
mInstanceState = null;
}
}
ok,原来是这样来更新的,明白了。
总结起来看,所有的Adapter都是BaseAdapter的子类,所有的带Adapter的view都是AdapterView的子类。AbsListView也是AdapterView的子类。
在View和Adapter关联的时候会把view的Oberver注册到adapter上,所以在adapter数据变化的时候。view就可以通过observer了解到,从而可以及时更新。
看来Adapter 模式的实现用了Oberver模式,隐隐约约还用到桥模式,不知道我的认识是不是正确呢。