系列笔记11、观察者模式-ListView与Adapter
2017-04-19 14:58
381 查看
Subject:抽象主题,也就是被观察者(Observable)
ConcreteSubject:具体主题
Observer:抽象观察者
ConcreteObserver:具体的观察者
观察者模式ListView与Adapter
ListView数据变化后,会调用Adapter的notifyDataSetChanged()方法,这个方法定义在BaseAdapter中
BaseAdapter.java
package android.widget;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
}
这是一个观察者模式。被观察者DataSetObservable,那么观察者是什么呢。
DataSetObservable.java
package android.database;
public class DataSetObservable extends Observable<DataSetObserver> {
public void notifyChanged() {
synchronized(mObservers) {
// 调用所有观察者的onChanged方式
//注意这里从后往前遍历,是为了防止app在onChanged()方法实现里,
//把自己从mObservers集合里移除了,这时候正向遍历就会引起问题
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
}
代码就是调用mObservers的onChanged()方法,那么这些观察者从哪里来的?其实是ListView在setAdapter()的时候设置的。
ListView.java
package android.widget;
public class ListView extends AbsListView {
public void setAdapter(ListAdapter adapter) {
...
if (mAdapter != null) {
...
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
}
}
package android.widget;
public abstract class AbsListView {
private FastScroller mFastScroll;
private void setFastScrollerEnabledUiThread(boolean enabled) {
if (mFastScroll != null) {
mFastScroll.setEnabled(enabled);
} else if (enabled) {
mFastScroll = new FastScroller(this, mFastScrollStyle);
mFastScroll.setEnabled(true);
}
...
}
/**
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
@Override
public void onChanged() {
super.onChanged();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
@Override
public void onInvalidated() {
super.onInvalidated();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
}
}
package android.widget;
public abstract class AdapterView<T extends Adapter> extends ViewGroup {
class AdapterDataSetObserver extends DataSetObserver {
@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()方法刷新布局
requestLayout();
}
}
整个流程是先在ListView的setAdapter()里给被观察者DataSetObservable注册观察者AbsListView.AdapterDataSetObserver,DataSetObservable放在BaseAdapter里引用,在数据发生变化时,调用adapter的notifyDataSetChanged()方法,而该方法其实是调用了DataSetObservable的notifyChanged()方法,最终会调用observer的onChanged()方法,也就是AdapterView.AdapterDataSetObserver实现的onChanged()方法,在这个方法里会调用对应ListView的requestLayout()去刷新布局。
ConcreteSubject:具体主题
Observer:抽象观察者
ConcreteObserver:具体的观察者
观察者模式ListView与Adapter
ListView数据变化后,会调用Adapter的notifyDataSetChanged()方法,这个方法定义在BaseAdapter中
BaseAdapter.java
package android.widget;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
}
这是一个观察者模式。被观察者DataSetObservable,那么观察者是什么呢。
DataSetObservable.java
package android.database;
public class DataSetObservable extends Observable<DataSetObserver> {
public void notifyChanged() {
synchronized(mObservers) {
// 调用所有观察者的onChanged方式
//注意这里从后往前遍历,是为了防止app在onChanged()方法实现里,
//把自己从mObservers集合里移除了,这时候正向遍历就会引起问题
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
}
代码就是调用mObservers的onChanged()方法,那么这些观察者从哪里来的?其实是ListView在setAdapter()的时候设置的。
ListView.java
package android.widget;
public class ListView extends AbsListView {
public void setAdapter(ListAdapter adapter) {
...
if (mAdapter != null) {
...
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
}
}
package android.widget;
public abstract class AbsListView {
private FastScroller mFastScroll;
private void setFastScrollerEnabledUiThread(boolean enabled) {
if (mFastScroll != null) {
mFastScroll.setEnabled(enabled);
} else if (enabled) {
mFastScroll = new FastScroller(this, mFastScrollStyle);
mFastScroll.setEnabled(true);
}
...
}
/**
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
@Override
public void onChanged() {
super.onChanged();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
@Override
public void onInvalidated() {
super.onInvalidated();
if (mFastScroll != null) {
mFastScroll.onSectionsChanged();
}
}
}
}
package android.widget;
public abstract class AdapterView<T extends Adapter> extends ViewGroup {
class AdapterDataSetObserver extends DataSetObserver {
@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()方法刷新布局
requestLayout();
}
}
整个流程是先在ListView的setAdapter()里给被观察者DataSetObservable注册观察者AbsListView.AdapterDataSetObserver,DataSetObservable放在BaseAdapter里引用,在数据发生变化时,调用adapter的notifyDataSetChanged()方法,而该方法其实是调用了DataSetObservable的notifyChanged()方法,最终会调用observer的onChanged()方法,也就是AdapterView.AdapterDataSetObserver实现的onChanged()方法,在这个方法里会调用对应ListView的requestLayout()去刷新布局。
相关文章推荐
- android 中ListView Adapter内所蕴含的观察者模式
- 最常用的Java设计之一 观察者模式 在android中的实例 ListView Adapter机制
- 11. JAVA常用类库 Part 4 (对象克隆技术clone、Arrays类、Comparable接口、比较器Comparator、观察者设计模式) ----- 学习笔记
- Android ListView与BaseAdapter的观察者模式实现
- PHP 设计模式 笔记与总结(11)观察者模式
- 系列笔记11.2、观察者模式BroadcastReceiver
- ListView BaseAdapter中的观察者模式
- (转)ListView BaseAdapter中的观察者模式
- ListView中的adapter的观察者模式
- Android进阶系列--源码分析观察者模式在ListView的运用
- 【安卓笔记】数据适配器(adapter)中的观察者模式
- 菜鸟学设计模式系列笔记之适配器模式(adapter模式)
- java设计模式学习系列之六:Observer, 观察者模式---小例
- 设计模式系列漫谈之一 - 观察者模式
- 阿Sam的设计模式学习笔记---- Adapter模式
- 设计模式学习笔记六——Adapter模式
- “凿壁借光”的模式场景——设计模式系列谈之Adapter模式
- 《让僵冷的翅膀飞起来》系列之二——从实例谈Adapter模式(转)
- 《Head.First设计模式》的学习笔记(3)--观察者模式
- “凿壁借光”的模式场景——设计模式系列谈之Adapter模式