android setonclick 观察者模式,从Android ListView 看Observer 观察者设计模式setOnClickListener...

这里我不说观察这模式的理论,定义。举例说明我对观察者设计模式的理解。

Android开发中经常用到:

mBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

}

});

这段代码中 mBtn 是被观察者, OnClickListener 是观察者。 二者通过setOnClickListener

() 方法达成订阅关系。setOnClickListener

方法使得mBtn保存了调用

onClick

()方法的机会。至于mBtn怎么去调用

onClick方法就看mBtn怎么去实现了,很明显当mBtn被点击的时候,就会去判断是否注册了onClick方法,如果有就调用。总结起来就是:

(Button-> 被观察者( Observable)、OnClickListener ->观察者(Observer)、setOnClickListener

() ->订阅(subscribe),onClick

() -> 事件(event))

观察者模式抽象出来就是: Observable.subscribe(Observer)

开始分析ListView:

mListView = (ListView) findViewById(R.id.listview);

mAdapter = new MyListAdapter(mContext, mListData);

mListView.setAdapter(mAdapter);

mAdapter.notifyDataSetChanged();

从上面四行对ListView的使用方式来看。

/************接口层 begin***********/

public abstract class Observable{

/**

* The list of observers. An observer can be in the list at most

* once and will never be null.

*/

protected final ArrayListmObservers = new ArrayList();

/**

* Adds an observer to the list. The observer cannot be null and it must not already

* be registered.

* @param observer the observer to register

* @throws IllegalArgumentException the observer is null

* @throws IllegalStateException the observer is already registered

*/

public void registerObserver(T observer) {

synchronized(mObservers) {

mObservers.add(observer);

}

}

}

/**

* Receives call backs when a data set has been changed, or made invalid. The typically data sets

* that are observed are {@link Cursor}s or {@link android.widget.Adapter}s.

* DataSetObserver must be implemented by objects which are added to a DataSetObservable.

*/

public abstract class DataSetObserver {

/**

* This method is called when the entire data set has changed,

* most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.

*/

public void onChanged() {

// Do nothing

}

}

public class DataSetObservable extends Observable{

/**

* Invokes {@link DataSetObserver#onChanged} on each observer.

* Called when the contents of the data set have changed. The recipient

* will obtain the new contents the next time it queries the data set.

*/

public void notifyChanged() {

synchronized(mObservers) {

// since onChanged() is implemented by the app, it could do anything, including

// removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

for (int i = mObservers.size() - 1; i >= 0; i--) {

mObservers.get(i).onChanged();

}

}

}

}

/************接口层 end***********/

/************中间层 begin***********/

public abstract class AdapterViewextends ViewGroup {

/* 改变View 的展示 */

class AdapterDataSetObserver extends DataSetObserver {

private Parcelable mInstanceState = null;

@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();//刷新view布局

}

}

}

public abstract class AbsListView extends AdapterView{

/**

* Should be used by subclasses to listen to changes in the dataset

*/

AdapterDataSetObserver mDataSetObserver;

/**

* The adapter containing the data to be displayed by this view

*/

ListAdapter mAdapter;

class AdapterDataSetObserver extends AdapterView.AdapterDataSetObserver {

@Override

public void onChanged() {

super.onChanged();

}

}

}

/*************中间层 end****************/

/*************最终实现层begin****************/

@RemoteView

public class ListView extends AbsListView {

/**

* Sets the data behind this ListView.

*

* The adapter passed to this method may be wrapped by a {@link WrapperListAdapter},

* depending on the ListView features currently in use. For instance, adding

* headers and/or footers will cause the adapter to be wrapped.

*

* @param adapter The ListAdapter which is responsible for maintaining the

* data backing this list and for producing a view to represent an

* item in that data set.

*

* @see #getAdapter()

*/

@Override

public void setAdapter(ListAdapter adapter) {

mAdapter = adapter;

}

mDataSetObserver = new AdapterDataSetObserver();

mAdapter.registerDataSetObserver(mDataSetObserver);

}

public abstract class BaseAdapter implements ListAdapter {

private final DataSetObservable mDataSetObservable = new DataSetObservable();

public void registerDataSetObserver(DataSetObserver observer) {

mDataSetObservable.registerObserver(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();

}

}

/*************最终实现层end************/







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值