設(shè)計模式-適配器adapter模式
- adapter模式詳解
-
adapter模式在android中的實際運用
1.listview用的adapter 、recyclerView 2.viewpager 3.java中的spring也用的多
11_1-11-7[00_50_58][20180731-232020-2].jpg
-
1.adapter模式詳解
1.適配器模式定義
將一個接口轉(zhuǎn)換成客戶希望的另一個接口缠黍,適配器模式使接口不兼容的那些類可以一起工作揍瑟,其別名為包裝器(wrapper)
適用場景:
1.需要接口轉(zhuǎn)換
2.需要重復(fù)使用的類少欺,同時重復(fù)的類彼此之間又沒有相同關(guān)系的喳瓣。
2.類適配器
1.類適配器定義
類的適配器模式將適配的類的API轉(zhuǎn)換成為目標(biāo)類的API
2.UML結(jié)構(gòu)圖解釋
圖:
《interface》
Target(目標(biāo)接口) Adaptee(不滿足要求的接口)
-------------- --------------
+sampleOperation1():void +sampleOperation1():void
+sampleOperation2():void
Adapter
----------------------
-adaptee :Adaptee
----------------------
+Adapter();
+sampleOperation1():void
+sampleOperation2():void
Adaptee這個類并沒有接口(目標(biāo)接口,客戶想要的功能) sampleOperation2這個方法
而我們需要 這個方法赞别,為了讓客戶端能用到該方法畏陕,同時又能使用adaptee這個類,所以提供了適配器中間環(huán)節(jié)仿滔,將Target和adaptee連接起來惠毁。同時非常重要的一點,Adapter和Adaptee是繼承關(guān)系,這是類適配器的特點
UML圖可是看出 繼承不兼容類崎页,實現(xiàn)接口-->將不兼容類適配給客戶 可用
總結(jié):
1.類適配器使用對象繼承的方式鞠绰,是靜態(tài)的定義方式
2.對于類適配器,適配器可以重新定義Adaptee的部分行為
3.對于類適配器飒焦,僅僅引入了一個對象蜈膨,并不需要額外的引用來間接得到Adaptee
4.對于類適配器,由于適配器直接繼承了Adaptee牺荠,使得適配器不能和Adaptee的子類一起工作
3.對象適配器
1.對象適配器定義
2.UML結(jié)構(gòu)圖解釋
3.code詳解
4.總結(jié)
1.對象適配器定義
與類的適配器模式一樣翁巍,對象的適配器模式把被適配的類的API轉(zhuǎn)換成為目標(biāo)類的API,與類的適配器模式不同的是休雌,對象適配器模式不是使用的繼承關(guān)系連接到Adaptee類曙咽,而是使用委派關(guān)系連接到Adaptee類。
《interface》
Target(目標(biāo)接口) Adaptee(不滿足要求的類)
-------------- --------------
+sampleOperation1():void +sampleOperation1():void
+sampleOperation2():void
Adapter
----------------------
-adaptee :Adaptee(對象適配器無)
----------------------
+Adapter();
+sampleOperation1():void (對象適配器無)
+sampleOperation2():void
圖:
Adapter實現(xiàn)了目標(biāo)接口挑辆,持有了被適配類的對象引用(而不是繼承)
適配器Adapter構(gòu)造方法 需要傳入?yún)?shù)Adaptee
public class Adapter implements Target{
private Adaptee mAdapteee;
public Adapter(Adaptee adaptee){mAdaptee = adaptee;}
public void simpleOperation1(){adaptee.xxx()}
public void simpleOperation2(){//空實現(xiàn)}
}
2.UML結(jié)構(gòu)圖解釋
3.code詳解
4.總結(jié)
對象適配器使用對象組合的方式,是動態(tài)組合的方式孝情。
對于對象適配器鱼蝉,一個適配器可以把多種不同的源 適配到同一個目標(biāo)
對于對象適配器而言,要重定義Adaptee的行為比較困難箫荡,不像繼承可以重寫
對于對象適配器魁亦,需要額外的引用來間接得到 被適配對象Adaptee
2.adapter模式在android中的實際運用
1.listview用的
1.UI
圖
Data Source--> <-- Adapter --> <-- ListView
|
| |
Cursor ArrayList
ListView是將各種各樣的數(shù)據(jù)源顯示成 各種各這樣的ItemView,
由于每一個我們想要顯示的效果是不相同的羔挡,同時要顯示的Data Source 以及他們的數(shù)量也是千變?nèi)f化的洁奈,如何應(yīng)對這種變化。
在 數(shù)據(jù)層 和View層 中間增加一個Adapter 來隔離變化绞灼。
將ListView所需要的關(guān)于ItemView的接口 抽象到Adapter 當(dāng)中利术,并且ListView內(nèi)部調(diào)用Adpater接口來完成我們整個數(shù)據(jù)和布局的顯示操作。
操作:主要實現(xiàn)BaseAdapter接口低矮,將adapter設(shè)置給listViw印叁,通過setAdapter方法。這樣ListView'可以按照我們想要的UI效果,數(shù)量顯示每個Item轮蜕。
ListView最重要的問題昨悼,解決每一項Item的數(shù)據(jù)輸出,Item它的View 是個性化定制跃洛,但根本 它是一個View率触。
--->adapter 作用:1.封裝數(shù)據(jù) 2.統(tǒng)一我們的ItemView,輸出View類型汇竭。這樣就很好的處理了ItemView千變?nèi)f化的特征性葱蝗。
UI總結(jié):
1.ListView 是由一條條的Item組成的,這每一條Item又是一個View韩玩。通過Adapter適配器這個橋梁將Viwe添加到ListView中垒玲。
2.一個Adapter是AdapterView 視圖與數(shù)據(jù)之間的橋梁,Adapter提供對數(shù)據(jù)的訪問找颓,也負(fù)責(zé)為每一項數(shù)據(jù)產(chǎn)生對應(yīng)的View
3.每一項數(shù)據(jù)產(chǎn)生對應(yīng)的View之后合愈,然后將View添加到ListView之中
4.MVC接口。Adapter是controller击狮,將數(shù)據(jù)源轉(zhuǎn)換成View
2.源碼
圖:
ListView:
無Adapter的成員變量佛析,放到了父類中AbsListView
AbsListView
方法 void onAttachedToWindow();當(dāng)我們的View關(guān)聯(lián)到指定的Window時調(diào)用
方法底部調(diào)用了 mItemCount = mAdapter.getCount(); ---需要重寫的方法之一
這之上new 了一個觀察者
mDataSetObserver = new AdapterDataSetObserver();//觀察者
aAdapter.registerDataSetObserver(mDataSetObserver);
這里是適配器和觀察者結(jié)合使用
--->當(dāng)數(shù)據(jù)源發(fā)生變化時,會通過適配器來通知整個觀察者來去做相應(yīng)的UI改變
onLayout方法中:
會調(diào)用void layoutChildren(){空實現(xiàn)}彪蓬,在子類ListView中實現(xiàn)
ListView的
layoutChildren(){}非常長
隨便看一個方法fillUp(int pos,int nextBottom) 從布局上開始填充
makeAndAddview(int postion寸莫,int y,boolean flow,int childrenLeft,boolean selected)//方法
這里的View是ListView中的每一個ItemView档冬,positon是位置
1.獲得View final View child = obtainView(position,mIsScrop)
2.設(shè)置View 布局到特定的位置
setupChild(child,position,y,flow,childrenLeft,selected,mIsScrop[0])
圖:
final View scrapView = mRecycler.getScrapView(position);
final View child = mAdapter.getView(position,scrapView,this);
11_1-11-7[00_50_58][20180731-232020-2].jpg
11_1-11-7[00_59_03][20180801-084247-3].jpg
11_1-11-7[01_03_25][20180801-204435-4].jpg
11_1-11-7[01_06_57][20180801-205543-5].jpg
11_1-11-7[01_09_47][20180801-210314-6].jpg
11_1-11-7[01_09_50][20180801-210341-7].jpg
11_1-11-7[01_11_12][20180801-211017-0].jpg
11_1-11-7[01_12_20][20180801-211133-1].jpg
11_1-11-7[01_13_47][20180801-211148-2].jpg