观察者的终极图:
![](https://img-blog.csdn.net/20151225221641360?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
核心:就是被观察者中持有观察的引用,可以在必要的时候进行调用观察者的方法进行通知它;
1. 观察者模式
定义对象间的一种一个(Subject)对多(Observer)的依赖关系,当一个对象的状态发送改变时,所以依赖于它的
对象都得到通知并被自动更新
2. MVC只是Observer模式的一个实例。Observer模式要解决的问题为:
* 建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,
* 依赖这个“一”的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,
* 我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。
* 这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。
3 .适用性:
当一个抽象模型有两个方面,其中一个方面依赖于另一方面
将这两者封装成独立的对象中以使它们可以各自独立的改变和服用
当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变
1. Subject(目标)
* 目标知道它的观察者,可以有任意多个观察者观察同一个目标
* 提供注册和删除观察者对象的接口
2. Observer(观察者)
* 为那些在目标发生改变时需获得通知的对象定义个更新的接口
3. ConcreteSubject(具体目标)
* 将有关状态存入各ConcreteObserver对象
* 当它的状态发送改变时,向它的各个观察者发出通知
4. ConcreteObserver(具体观察者)
* 维护一个指向ConcreteObserver对象的引用
* 存储有关状态,这些状态应与目标的状态保持一致
* 实现Observer的更新接口是自身状态与目标的状态保持一致
BaseAdapter 类的简单分析:
内部封装了一个被观察者对象,间接的实现了自己作为被观察者;
就是一个接口实现它可以进行成为被观察者,来进行注册, 删除,通知 内容观察者使用的定义了集合可以存放多个观察者。
Listview的setAdapter的方法的简介:
通过listview的setAdapter的方法可以进行给adapter进行注册观察者。重点:此处让listview和adapter进行联系起来了;问题的关键在于如何让adapter的观察者和listview联系起来;就是观察者和listview的关系,就是
观察者得到adapter的通知之后如何进行ui的更新的操作。
AdapterDataSetObserver是listview的内部类,内部类有指向外部的引用,可以直接调用外部类的方法。所以在该类中可以进行调用更新listview方法了。
mAdapter.registerDataSetObserver(mDataSetObserver); }
Listview的父类:
public abstract class AbsListView extends AdapterView<ListAdapter>
AdapterDatasetObserver类的简介:
是listview的父类的内部类的,同时也继承于listview爷爷类(AdapterView)的内部类。
核心:就是被观察者中持有观察的引用,可以在必要的时候进行调用观察者的方法进行通知它;
1. 观察者模式
定义对象间的一种一个(Subject)对多(Observer)的依赖关系,当一个对象的状态发送改变时,所以依赖于它的
对象都得到通知并被自动更新
2. MVC只是Observer模式的一个实例。Observer模式要解决的问题为:
* 建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,
* 依赖这个“一”的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,
* 我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。
* 这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。
3 .适用性:
当一个抽象模型有两个方面,其中一个方面依赖于另一方面
将这两者封装成独立的对象中以使它们可以各自独立的改变和服用
当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变
当一个对象必须通知其它对象,而它又不能假定其它对象是谁
具体分析:
参与者:1. Subject(目标)
* 目标知道它的观察者,可以有任意多个观察者观察同一个目标
* 提供注册和删除观察者对象的接口
2. Observer(观察者)
* 为那些在目标发生改变时需获得通知的对象定义个更新的接口
3. ConcreteSubject(具体目标)
* 将有关状态存入各ConcreteObserver对象
* 当它的状态发送改变时,向它的各个观察者发出通知
4. ConcreteObserver(具体观察者)
* 维护一个指向ConcreteObserver对象的引用
* 存储有关状态,这些状态应与目标的状态保持一致
* 实现Observer的更新接口是自身状态与目标的状态保持一致
BaseAdapter 类的简单分析:
内部封装了一个被观察者对象,间接的实现了自己作为被观察者;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public void registerDataSetObserver(DataSetObserver //观察者类observer) {
DataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.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();
}
}
}
Observable的源码简单解析:
就是一个接口实现它可以进行成为被观察者,来进行注册, 删除,通知 内容观察者使用的定义了集合可以存放多个观察者。
public abstract class Observable<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
public void registerObserver(T observer) {
mObservers.add(observer);
}
}
通过分析可以得到一个adapter其实就是一个包装的被观察者对象,里面可以进行注测多个观察者。
Listview的setAdapter的方法的简介:
通过listview的setAdapter的方法可以进行给adapter进行注册观察者。重点:此处让listview和adapter进行联系起来了;问题的关键在于如何让adapter的观察者和listview联系起来;就是观察者和listview的关系,就是
观察者得到adapter的通知之后如何进行ui的更新的操作。
public void setAdapter(ListAdapter adapter) {
mAdapter = adapter;
if (mAdapter != null) {
mDataSetObserver = new AdapterDataSetObserver();
该类是观察者和listview进行联系起来的关键所在的,因为
AdapterDataSetObserver是listview的内部类,内部类有指向外部的引用,可以直接调用外部类的方法。所以在该类中可以进行调用更新listview方法了。
mAdapter.registerDataSetObserver(mDataSetObserver); }
Listview的父类:
public abstract class AbsListView extends AdapterView<ListAdapter>
AdapterDatasetObserver类的简介:
是listview的父类的内部类的,同时也继承于listview爷爷类(AdapterView)的内部类。
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
@Override
public void onChanged() {
super.onChanged();
通过调用父类的方法去更新的ui的操作;因为父类已经写好了操作;
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
}
public abstract class AdapterView<T extends Adapter> extends ViewGroup {
class AdapterDataSetObserver extends DataSetObserver {
public void onChanged() {
…….
在父类的onchanged的方法中进行,requestLayout的方法,该方法会进行重新的布局和更新ui的操作。此时就完成了适配器通知listview更新的操作;