您的位置:首页 > 其它

观察者设计模式--listView的源码分析

2016-11-30 15:34 579 查看
观察者设计模式:定义一个对象间一种一对多的依赖关系,当一个对象改变状态,则所有依赖他的对象都会得到通知并且自动更新定义一种对象之间一对多的依赖关系, 当一个对象改变状态,则依赖他的对象都会得到通知并且自动更新角色介绍:抽象主题: 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.csdn.net/bboyfeiyu/article/details/44040533
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ListView