Adapter在Android中佔據一個重要的角色,它是數據和UI(View)之間一個重要的紐帶。android
在常見的View(ListView,GridView)等地方都須要用到Adapter。如圖1直觀的表達了Data、Adapter、View三者的關係。數據庫
圖1 Adapter、數據、UI三者關係(PS:此圖來自Google I/O)數組
Android中Adapterapp
圖2:Android中Adapter類型層級圖函數
adapter如同其自己含義,其實就是一個適配器,他能夠對要顯示的數據進行統一的封裝,主要是將數據變成view提供給list。ui
咱們先來看看adapter的體系:spa
public interface Adapter----0層(表示繼承體系中的層次)對象
public interface ExpandableListAdapter---(無所謂層次由於沒有其餘接口繼承實現它)繼承
這是adapter的始祖,其餘個性化的adapter均實現它並加入本身的接口。接口
public interface ListAdapter----1層
public interface SpinnerAdapter----1層
public interface WrapperListAdapter----2層(實現ListAdapter)
以上接口層面上的體系已經完了。
能夠看出來做爲widget view的橋樑adapter其實只分爲2種:ListAdapter和SpinnerAdapter以及ExpandableListAdapter。也就是說全部widget也就是基於list和spinne與ExpandableList三種view形式的。
因爲在實際使用時,咱們須要將數據加入到Adapter,而以接口形式呈現的adapter沒法保存數據,因而Adapter就轉型爲類的模式。
public abstract class BaseAdapter----2層(實現了ListAdapter和SpinnerAdapter)
以抽象類的形式出現構造了類型態下的頂層抽象,包容了List和Spinner
public class ArrayAdapter----3層
public class SimpleAdapter---3層
public class CursorAdapter----3層(CursorAdapter其後還有子類這裏先不探討)
基本體系有了以後,讓咱們看看頂層Adapter裏有哪些方法(只列舉經常使用的):
abstract Object getItem(int position)
abstract int getCount()
abstract long getItemId(int position)
abstract int getItemViewType(int position)
abstract View getView(int position,View convertVeiw,ViewGroup parent)
以上是比較重要的方法,ArrayAdapter他們也是從新實現以上方法的。在實際的開發過程當中,每每咱們要本身作屬於本身的Adapter,以上方法都是須要從新實現的。
由圖2咱們能夠看到在Android中與Adapter有關的全部接口、類的完整層級圖。在咱們使用過程當中能夠根據本身的需求實現接口或者繼承類進行必定的擴展。
比較經常使用的有BaseAdapter,ArrayAdapter,SimpleCursorAdapter等。
· BaseAdapter是一個抽象類,繼承它須要實現較多的方法,因此也就具備較高的靈活性;
· ArrayAdapter支持泛型操做,一般須要實現getView方法,特殊狀況下(結合數據row id),爲了讓ui事件相應處理方便點最好重寫getItemId;
· SimpleCursorAdapter能夠適用於簡單的純文字型ListView,它須要Cursor的字段和UI的id對應起來。如須要實現更復雜的UI也能夠重寫其餘方法。
· 若你的數據來源於一個Arraylist 就使用BaseAdapter,SimpleAdapter,而數據來源於經過查詢數據庫得到Cursor那就使用SimpleCursorAdapter等。
下面分別講一下它的幾個常見的子類:
ListAdapter接口:繼承於Adapter。ListAdapter是一個ListView和list上的數據之間的橋樑。數據常常來自於一個Cursor,但這不是必須的。ListView能顯示任何數據,只要它是被一個ListAdapter包裝的。
BaseAdapter抽象類:是一個實現了既能在ListView(實現了ListAdapter接口)和Spinner(實現了Spinner 接口)裏用的Adapter類的通常基類。
ArrayAdapter類:一個管理這樣的ListView的ListAdapter:這個ListView被一個數組所支持。這個數組可裝任意對象。默認狀態下,這個類預期能這樣:提供的資源id與一個單獨的TextView相關聯。若是你想用一個更復雜的layout,就要用包含了域id的構造函數。這個域id可以與一個在更大的layout資源裏的TextView相關聯。它將被在數組裏的每一個對象的toString()方法所填滿。你能夠添加一般對象的lists或arrays。重寫你對象的toString()方法來決定list裏哪個寫有數據的text將被顯示。若是想用一些其它的不一樣於TextView的view來顯示數組(好比ImageViews),或想有一些除了toString()返回值所填在views裏的之外的數據,你就要重寫getView(int,View,ViewGroup)方法來返回你想要的View類型。
getView 方法的做用是獲得一個View,這個view顯示數據項裏指定位置的數據,你能夠或者手動建立一個view或者從一個XML layout中inflate。當這個view被inflated,它的父view(如GridView,ListView等)將要使用默認的layout參數,除非你用inflate(int,android.view.ViewGroup,boolean)方法來指定一個根view並防止附着在根上。
SimpleAdapter類:一個使靜態數據和在XML中定義的Views對應起來的簡單adapter。你能夠把list上的數據指定爲一個Map範型的ArrayList。ArrayList裏的每個條目對應於list裏的一行。Maps包含着每一行的數據。你先要指定一個XML,這個XML定義了用於顯示一行的view。你還要指定一個對應關係,這個對應關係是從Map的keys對應到指定的views。
綁定數據到views發生在兩個階段:若是一個simpleAdapter.ViewBinder是可用的,那麼SetViewValue(android.view.View,Object,String)要被調用。若是返回true,那麼綁定發生了。若是返回false,那麼以下views將被按順序地嘗試:
~實現了Checkable的View(如CheckBox),預期的綁定值是boolen
~TextView,預期的綁定值是String,而且SetViewText方法被調用
~ImageView,預期的綁定值是一個資源的id或String。而且SetViewImage方法被調用
若是沒有合適的綁定被發現,一個IllegalStateException被拋出。