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

观察者设计模式:
定义一个对象间一种一对多的依赖关系,当一个对象改变状态,则所有依赖他的对象都会得到通知并且自动更新
定义一种对象之间一对多的依赖关系, 当一个对象改变状态,则依赖他的对象都会得到通知并且自动更新

角色介绍:
抽象主题: 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值