观察者设计模式:
定义一个对象间一种一对多的依赖关系,当一个对象改变状态,则所有依赖他的对象都会得到通知并且自动更新
定义一种对象之间一对多的依赖关系, 当一个对象改变状态,则依赖他的对象都会得到通知并且自动更新
角色介绍:
抽象主题: subject
抽象主题角色把所有的观察者对象的引用保存在一个聚集里 比如 ArrayList ,每个主题都可以 有任意数量的观察者, 抽象主题提供一个借口, 可以增加或者删除观察者对象,抽象主题又叫抽象被观察者对象 Observable
具体主题:ConcreteSubject
将有关状态存入具体的观察者对象;在具体主题内部发生改变的时候,给所有登记过的观察者发送通知 具体主题角色又叫具体被观察者
抽象观察者:Observer
为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个借口叫做更新接口
具体观察者:ConcreteObserver
存储与主题的状态自怡的状态,具体的观察者实现抽象
观察者所要求的更新接口,以便使本身的状态与主题的状态相协调。
baseAdapter就是一个观察者设计模式,
listView更新完数据,会调用一个方法,notifyDataSetChanged()
Observer 抽象观察者
Observable 抽象被观察者 也就是subject 抽象主题
BaseAdapter是一个观察者模式:
源码中:
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
//DataSetObservable 就是一个数据集的 被观察者
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public boolean hasStableIds() {
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
/**
* 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();
}
mDataSetObservable
.
notifyChanged
();进入到notifyChanged()
public class DataSetObservable extends Observable<DataSetObserver> {
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
遍历了所有的观察者,并且调用他们的
onChange()方法
这些观察者 哪来?
public void setAdapter(ListAdapter adapter) {
//如果有adapter 先注销该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();//将这个观察者注册到Adapter中 实际上是注册到DataSetObserver中
mAdapter.registerDataSetObserver(mDataSetObserver);
设置adapter的时候,会构建一个AdapterDataSetObserver ,然后将这个观察者注册到adapter中 这样 观察者和被观察者都有了 一般数据集就放到了Adapter 中
数据集一般来自adapter中 比如:
public abstract class UserAdapter extends BaseAdapter {
// 数据集
protected List<String> mDataSet = new LinkedList<String>();
protected Context mContext = null;
public CommonAdapter(Context context, List<String> dataSet) {
this.mDataSet = dataSet;
this.mContext = context;
}
}
AdapterDataSetObserver 继承DataSetObserver
class AdapterDataSetObserver extends DataSetObserver {
private Parcelable mInstanceState = null;
// 上文有说道,调用Adapter的notifyDataSetChanged的时候会调用所有观察者的onChanged方法,核心实现就在这里
@Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
// 获取Adapter中数据的数量
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();
// 重新布局ListView、GridView等AdapterView组件
requestLayout();
}
// 代码省略
public void clearSavedState() {
mInstanceState = null;
}
}
当调用notifyDataChange这个函数的时候,这个函数会调用DataSetObservable 的notifyChange函数, 这个函数会调用所有观察者(AdapterDataSetObserver)的onChange()方法
来源:
http://blog.youkuaiyun.com/bboyfeiyu/article/details/44040533