Android Listview 中的觀察者模式圖示與代碼分析

在這裏插入圖片描述

代碼分析:
參與其中的總共八個對象,分別是ListviewAbsListViewArrayAdapterBaseAdapterAdapterDataSetObserverDataSetObserverDataSetObservableObservable

四個抽象對象,四個實體對象。

  1. 首先,DataSetObserver定義了兩個方法給子類繼承,用於通知更改
public abstract class DataSetObserver {
    public void onChanged() {}
    public void onInvalidated() {}
}
  1. 然後AdapterDataSetObserver繼承了這兩個方法,在onChanged的時候申請了重繪視圖
class AdapterDataSetObserver extends DataSetObserver {
    @Override
    public void onChanged() {
   		...
		requestLayout(); //這個是向系統申請重新繪製視圖的方法
	}
}
  1. Listview 繼承 AbsListView,我們在給它設置setAdapter的時候,創建了AdapterDataSetObserver

@Override
public void setAdapter(ListAdapter adapter) {
	...
      mDataSetObserver = new AdapterDataSetObserver();
      mAdapter.registerDataSetObserver(mDataSetObserver);
	...
}

同時,把這個AdapterDataSetObserver註冊到了mAdapter裏。

  1. 另一邊,抽象類Observable<T>維護了一個ArrayList,用來存放觀察者
public abstract class Observable<T> {
	protected final ArrayList<T> mObservers = new ArrayList<T>();
	public void registerObserver(T observer) {...}
	public void unregisterObserver(T observer) {...}
}
  1. DataSetObservable繼承 Observable<DataSetObserver>並指定了泛型類型爲前面的DataSetObserver抽象觀察者
public void notifyChanged() {
   synchronized(mObservers) {
       for (int i = mObservers.size() - 1; i >= 0; i--) {
           mObservers.get(i).onChanged();
       }
   }
}
public void notifyInvalidated() {
    synchronized (mObservers) {
        for (int i = mObservers.size() - 1; i >= 0; i--) {
            mObservers.get(i).onInvalidated();
        }
    }
}
  1. 在ArrayAdapter的父類BaseAdapter中創建了DataSetObservable;
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();
    }
    public void notifyDataSetInvalidated() {
        mDataSetObservable.notifyInvalidated();
    }

這樣一來,ArrayAdapter 其實默認就擁有了四個方法,

registerDataSetObserver
unregisterDataSetObserver
notifyDataSetChanged
notifyDataSetInvalidated

現在都準備好了,
當我們創建Listview後,就給它設置adapter,這時,adapter順便把Listview裏的AdapterDataSetObserver註冊到了ArrayList<T> mObservers觀察者列表裏。
當我們更新Listview列表數據時,就要調用adapternotifyDataSetChanged,這樣就會去遍歷所有ArrayList<T> mObservers集合裏的觀察者,並調用他們的onChanged,此時,Listview裏的AdapterDataSetObserver就會調用onChanged,從而申請Listview重新繪製。這樣Listview就會刷新顯示了。


代碼看完了,現在假如我們自己要寫個觀察者模式怎麼做?

1.新建抽象觀察者,只寫抽象方法,用來接收信號

public abstract class 抽象觀察者{
	public void 接收信號{};
}

2.新建具體觀察者,重載方法,用來做具體收到信號後幹什麼

public class 實際觀察者 extends 抽象觀察者{
	@Override
	public void 接收信號{
		宣告世界,我收到信號了.
	}
}

3.新建抽象被觀察者,保存一個List集合,用來存儲所有觀察者。

public abstract class 抽象被觀察者<T> {
	protected final ArrayList<T> mObservers = new ArrayList<T>();
	public void 添加到集合(T observer) {...}
	public void 從集合刪除(T observer) {...}
}

4.新建具體被觀察者,用來更新數據,通知他人。

public class 具體被觀察者<泛型指定抽象觀察者> {
public void 通知所有人() {
   synchronized(mObservers) {
       for (int i = mObservers.size() - 1; i >= 0; i--) {
           mObservers.get(i).接收信號();
       }
   }
}

5.基本四個類已經寫好了,剩下的就是註冊和使用了。
先寫服務端,用來註冊和通知。

public class 服務端{
	//新建一個具體被觀察者
	new 具體被觀察者
	//提供方法用來把觀察者添加和刪除被觀察者的集合裏
	public void 添加觀察者{
		具體觀察者.添加到集合();
	}
	...
}

新建客戶端,用來接收通知。

public class 客戶端 {
	//新建一個觀察者
	new 實際觀察者 
	//獲取
	設置服務端
	//調用服務端的添加刪除方法,把這裏的實際觀察者放到服務端那邊
	服務端.添加觀察者

	//現在一切都設置好了。
	//當服務端有了新通知的時候
	具體的,比如網絡那邊有新消息發給你了
	這時候服務端就會調用具體的被觀察者去發送通知
	然後客戶端這裏的觀察者就會收到通知。
}
實際上總共就四個對象。
  • A想接收信號類
  • B想發送信號的類
  • C可以觀察接收信號的類
  • D可以發送信號的類

然後ABCD都可以做抽象繼承,這樣就會有8個類了,簡單點寫就是4個類了。

操作過程:
  • 新建的時候,A裏面新建C 持有B,B裏面新建D ,A讓B把C放到D的列表裏
  • 更新的時候,B讓D,向D的列表裏所有的C發送信號,這時候A裏面的C就會接收到信號
總結:

實際上就是搞清楚一下幾點。

  1. 誰想接收信號 就新建一個觀察者,添加到集合裏
  2. 誰想發送信號 就新建一個被觀察者,提供方法來添加和刪除,以及通知消息
  3. 誰可以發出信號 就用一個集合來存儲那些觀察者,並提供方法遍歷集合發送消息
  4. 誰可以接收信號 就用來接收消息,做你想做的事
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章