从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<T> {
    
	/**
     * The list of observers.  An observer can be in the list at most
     * once and will never be null.
     */
    protected final ArrayList<T> mObservers = new ArrayList<T>();

	/**
     * 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<DataSetObserver> {
    /**
     * 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 AdapterView<T extends Adapter> extends 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<ListAdapter>  {

	/**
     * 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<ListAdapter>.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、付费专栏及课程。

余额充值