# 2.4.4 Adapter基礎講解
## 本節引言
> 從本節開始我們要講的UI控件都是跟Adapter(適配器)打交道的,了解并學會使用這個Adapter很重要, Adapter是用來幫助填充數據的中間橋梁,簡單點說就是:將各種數據以合適的形式顯示到view上,提供 給用戶看!
## 1.MVC模式的簡單理解
> 在開始學習Adapter之前我們要來了解下這個MVC模式概念: 舉個例子:大型的商業程序通常由多人一同開發完成,比如有人負責操作接口的規劃與設計, 有人負責程序代碼的編寫如果要能夠做到程序項目的分工就必須在程序的結構上做適合的安排 ,如果,接口設計與修改都涉及到程序代碼的改變的話,那么兩者的分工就會造成執行上的困難 良好的程序架構師將整個程序項目劃分為如圖的三個部分:

**關系圖解析:**
> * **Model**:通常可以理解為數據,負責執行程序的核心運算與判斷邏輯,,通過view獲得用戶 輸入的數據,然后根據從數據庫查詢相關的信息,最后進行運算和判斷,再將得到的結果交給view來顯示
> * **view**:用戶的操作接口,說白了就是GUI,應該使用哪種接口組件,組件間的排列位置與順序都需要設計
> * **Controller**:控制器,作為model與view之間的樞紐,負責控制程序的執行流程以及對象之間的一個互動
而這個Adapter則是中間的這個Controller的部分: **Model**(數據) ---> **Controller**(以什么方式顯示到)---> **View**(用戶界面) 這就是簡單MVC組件的簡單理解!
## 2.Adapter概念解析
官方文檔:[Adapter](http://androiddoc.qiniudn.com/reference/android/widget/Adapter.html)
首先我們來看看他的繼承結構圖:

上面就是Adapter以及繼承結構圖了,接著我們介紹一下實際開發中還用到的幾個Adapter吧!
> * **BaseAdapter**:抽象類,實際開發中我們會繼承這個類并且重寫相關方法,用得最多的一個Adapter!
> * **ArrayAdapter**:支持泛型操作,最簡單的一個Adapter,只能展現一行文字~
> * **SimpleAdapter**:同樣具有良好擴展性的一個Adapter,可以自定義多種效果!
> * **SimpleCursorAdapter**:用于顯示簡單文本類型的listView,一般在數據庫那里會用到,不過有點過時, 不推薦使用!
其實一個BaseAdapter就夠玩的了,至于其他的,實際開發中用得不多,后面用到在講解~
## 3.代碼示例:
好的,多說無益,寫代碼最實際,接下來我們來用寫幾個簡單的Adapter實例, 幫助我們了解Adapter給我們帶來的便利,另外,因為Adapter需要結合ListView, GridView等等控件講解,一些高級一點的用法我們都放在ListView那里講! 這里就簡單演示下效果,另外這里用到的控件是ListView,下一節就會講解, 現在看不懂也沒關系!
### 1)ArrayAdapter使用示例:
**運行效果圖:**

**代碼實現:**
```
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//要顯示的數據
String[] strs = {"基神","B神","翔神","曹神","J神"};
//創建ArrayAdapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_expandable_list_item_1,strs);
//獲取ListView對象,通過調用setAdapter方法為ListView設置Adapter設置適配器
ListView list_test = (ListView) findViewById(R.id.list_test);
list_test.setAdapter(adapter);
}
}
```
**一些相關的東西:**
**1.**除了通過數組外,我們還可以寫到一個數組資源文件中:
比如:在res\valuse下創建一個數組資源的xml文件:**arrays.xml**:
```
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="myarray">
<item>語文</item>
<item>數學</item>
<item>英語</item>
</string-array>
</resources>
```
接著布局的listview屬性設置下這個列表項:
```
<ListView
android:id="@id/list_test"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:entries="@array/myarray"/>
```
就可以了~
當然我們也可以在Java代碼中這樣寫:
```
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.myarray,android.R.layout.simple_list_item_multiple_choice );
```
同樣也是可以的!
**2.**一開始也說了這個ArrayAdapter支持泛型,那么集合必不可少啦,比如,這樣寫:
```
List<String> data = new ArrayList<String>();
data.add("基神");
data.add("B神");
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_expandable_list_item_1,data);
```
就可以了~
**3.**我們看到了在實例化ArrayAdapter的第二個參數: **android.R.layout.simple_expandable_list_item_1** 其實這些是系統給我們提供好的一些ListView模板,有下面幾種:
> **simple_list_item_1** : 單獨一行的文本框  **simple_list_item_2** : 兩個文本框組成  **simple_list_item_checked** : 每項都是由一個已選中的列表項  **simple_list_item_multiple_choice** : 都帶有一個復選框  **simple_list_item_single_choice** : 都帶有一個單選鈕 
### 2)SimpleAdapter使用示例:
SimpleAdapter:簡單的Adapter,看似簡單,功能強大,下面我們來寫個稍微復雜一點的列表 布局吧!
**運行效果圖:**

**代碼實現:**
先來編寫一個列表項目每一項的布局:
**list_item.xml**
```
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 定義一個用于顯示頭像的ImageView -->
<ImageView
android:id="@+id/imgtou"
android:layout_width="64dp"
android:layout_height="64dp"
android:baselineAlignBottom="true"
android:paddingLeft="8dp" />
<!-- 定義一個豎直方向的LinearLayout,把QQ呢稱與說說的文本框設置出來 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:textColor="#1D1D1C"
android:textSize="20sp" />
<TextView
android:id="@+id/says"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8px"
android:textColor="#B4B4B9"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
```
接下來是**MainActivity.java**:
```
public class MainActivity extends AppCompatActivity {
private String[] names = new String[]{"B神", "基神", "曹神"};
private String[] says = new String[]{"無形被黑,最為致命", "大神好厲害~", "我將帶頭日狗~"};
private int[] imgIds = new int[]{R.mipmap.head_icon1, R.mipmap.head_icon2, R.mipmap.head_icon3};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>();
for (int i = 0; i < names.length; i++) {
Map<String, Object> showitem = new HashMap<String, Object>();
showitem.put("touxiang", imgIds[i]);
showitem.put("name", names[i]);
showitem.put("says", says[i]);
listitem.add(showitem);
}
//創建一個simpleAdapter
SimpleAdapter myAdapter = new SimpleAdapter(getApplicationContext(), listitem, R.layout.list_item, new String[]{"touxiang", "name", "says"}, new int[]{R.id.imgtou, R.id.name, R.id.says});
ListView listView = (ListView) findViewById(R.id.list_test);
listView.setAdapter(myAdapter);
}
}
```
好的,上面就是SimpleAdapter的簡單用法了,有點意思~
### 3)SimpleCursorAdapter使用示例:
雖然這東西過時了,不過對于不怎么會SQLite的初學者來說,用起來還是蠻方便的! 記得前面我們學ContentProivder寫過的讀取聯系人的例子么?之前是通過打印Log的 方式顯示出來,現在我們通過這個SimpleCursorAdapter把它顯示到ListView上!
**實現效果圖**:

**代碼實現**:
先寫下listView每個item的布局:
**list_item.xml**:
```
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/list_name"
android:layout_width="0dp"
android:layout_height="64dp"
android:layout_weight="1"
android:gravity="center"
android:text="小豬"
android:textColor="#0000FF"
android:textSize="18sp" />
<TextView
android:id="@+id/list_phone"
android:layout_width="0dp"
android:layout_height="64dp"
android:layout_weight="1"
android:gravity="center"
android:text="13798989898"
android:textColor="#EA5C4D"
android:textSize="18sp" />
</LinearLayout>
```
接著activity_main布局和前面的一樣,就是簡單的ListView,然后是
**MainActivity.java**:
```
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list_test = (ListView) findViewById(R.id.list_test);
//讀取聯系人
Cursor cursor = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
SimpleCursorAdapter spcAdapter = new SimpleCursorAdapter(this,R.layout.list_item,cursor,
new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER},
new int[]{R.id.list_name,R.id.list_phone});
list_test.setAdapter(spcAdapter);
}
}
```
最后AndroidManifest.xml里加個讀聯系人的權限就可以了!
```
<uses-permission android:name="android.permission.READ_CONTACTS"/>
```
**一問一答:**
> **問**:就這么簡單?
> **——答**:是的,直接獲取到Cursor,然后綁定就好了,無需你自己再寫什么SQL語句!
> **問**:你說這東西過時了,那拿什么來代替?
> **——答**:一般的做法是自己重寫BaseAdapter,獲取到數據集合后跟對應的控件進行綁定!
> **問**:這個SimpleCursorAdapter還有沒有要注意的地方?
> **——答**:有,使用SimpleCursorAdapter的話,綁定的數據庫表中一定要有_id這個字段, 或者as_ id;而且在綁定時取出的數據必須包含這個_id_項,否則的話會報以下錯誤! **java.lang.IllegalArgumentException: column '**id' does not exist**
## 本節小結:
> 好的,關于Adapter的基礎講解就到這里,當然我們這里講解的三個Adapter,我們實際開發中... 基本上用不到,哈哈,除了SimpleAdapter偶爾可能會用下,一般我們都是重寫BaseAdapter的!
> 另外,關于BaseAdapter的,有很多東西要講解,就把他丟到ListView那里一起講,畢竟Adapter 總是和View沾邊,而且ListView是我們用得最多的一個空間~嗯,本節就到這里,謝謝~
- 1.0 Android基礎入門教程
- 1.0.1 2015年最新Android基礎入門教程目錄
- 1.1 背景相關與系統架構分析
- 1.2 開發環境搭建
- 1.2.1 使用Eclipse + ADT + SDK開發Android APP
- 1.2.2 使用Android Studio開發Android APP
- 1.3 SDK更新不了問題解決
- 1.4 Genymotion模擬器安裝
- 1.5.1 Git使用教程之本地倉庫的基本操作
- 1.5.2 Git之使用GitHub搭建遠程倉庫
- 1.6 .9(九妹)圖片怎么玩
- 1.7 界面原型設計
- 1.8 工程相關解析(各種文件,資源訪問)
- 1.9 Android程序簽名打包
- 1.11 反編譯APK獲取代碼&資源
- 2.1 View與ViewGroup的概念
- 2.2.1 LinearLayout(線性布局)
- 2.2.2 RelativeLayout(相對布局)
- 2.2.3 TableLayout(表格布局)
- 2.2.4 FrameLayout(幀布局)
- 2.2.5 GridLayout(網格布局)
- 2.2.6 AbsoluteLayout(絕對布局)
- 2.3.1 TextView(文本框)詳解
- 2.3.2 EditText(輸入框)詳解
- 2.3.3 Button(按鈕)與ImageButton(圖像按鈕)
- 2.3.4 ImageView(圖像視圖)
- 2.3.5.RadioButton(單選按鈕)&Checkbox(復選框)
- 2.3.6 開關按鈕ToggleButton和開關Switch
- 2.3.7 ProgressBar(進度條)
- 2.3.8 SeekBar(拖動條)
- 2.3.9 RatingBar(星級評分條)
- 2.4.1 ScrollView(滾動條)
- 2.4.2 Date & Time組件(上)
- 2.4.3 Date & Time組件(下)
- 2.4.4 Adapter基礎講解
- 2.4.5 ListView簡單實用
- 2.4.6 BaseAdapter優化
- 2.4.7ListView的焦點問題
- 2.4.8 ListView之checkbox錯位問題解決
- 2.4.9 ListView的數據更新問題
- 2.5.0 構建一個可復用的自定義BaseAdapter
- 2.5.1 ListView Item多布局的實現
- 2.5.2 GridView(網格視圖)的基本使用
- 2.5.3 Spinner(列表選項框)的基本使用
- 2.5.4 AutoCompleteTextView(自動完成文本框)的基本使用
- 2.5.5 ExpandableListView(可折疊列表)的基本使用
- 2.5.6 ViewFlipper(翻轉視圖)的基本使用
- 2.5.7 Toast(吐司)的基本使用
- 2.5.8 Notification(狀態欄通知)詳解
- 2.5.9 AlertDialog(對話框)詳解
- 2.6.0 其他幾種常用對話框基本使用
- 2.6.1 PopupWindow(懸浮框)的基本使用
- 2.6.2 菜單(Menu)
- 2.6.3 ViewPager的簡單使用
- 2.6.4 DrawerLayout(官方側滑菜單)的簡單使用
- 3.1.1 基于監聽的事件處理機制
- 3.2 基于回調的事件處理機制
- 3.3 Handler消息傳遞機制淺析
- 3.4 TouchListener PK OnTouchEvent + 多點觸碰
- 3.5 監聽EditText的內容變化
- 3.6 響應系統設置的事件(Configuration類)
- 3.7 AnsyncTask異步任務
- 3.8 Gestures(手勢)
- 4.1.1 Activity初學乍練
- 4.1.2 Activity初窺門徑
- 4.1.3 Activity登堂入室
- 4.2.1 Service初涉
- 4.2.2 Service進階
- 4.2.3 Service精通
- 4.3.1 BroadcastReceiver牛刀小試
- 4.3.2 BroadcastReceiver庖丁解牛
- 4.4.2 ContentProvider再探——Document Provider
- 4.5.1 Intent的基本使用
- 4.5.2 Intent之復雜數據的傳遞
- 5.1 Fragment基本概述
- 5.2.1 Fragment實例精講——底部導航欄的實現(方法1)
- 5.2.2 Fragment實例精講——底部導航欄的實現(方法2)
- 5.2.3 Fragment實例精講——底部導航欄的實現(方法3)
- 5.2.4 Fragment實例精講——底部導航欄+ViewPager滑動切換頁面
- 5.2.5 Fragment實例精講——新聞(購物)類App列表Fragment的簡單實現
- 6.1 數據存儲與訪問之——文件存儲讀寫
- 6.2 數據存儲與訪問之——SharedPreferences保存用戶偏好參數
- 6.3.1 數據存儲與訪問之——初見SQLite數據庫
- 6.3.2 數據存儲與訪問之——又見SQLite數據庫
- 7.1.1 Android網絡編程要學的東西與Http協議學習
- 7.1.2 Android Http請求頭與響應頭的學習
- 7.1.3 Android HTTP請求方式:HttpURLConnection
- 7.1.4 Android HTTP請求方式:HttpClient
- 7.2.1 Android XML數據解析
- 7.2.2 Android JSON數據解析
- 7.3.1 Android 文件上傳
- 7.3.2 Android 文件下載(1)
- 7.3.3 Android 文件下載(2)
- 7.4 Android 調用 WebService
- 7.5.1 WebView(網頁視圖)基本用法
- 7.5.2 WebView和JavaScrip交互基礎
- 7.5.3 Android 4.4后WebView的一些注意事項
- 7.5.4 WebView文件下載
- 7.5.5 WebView緩存問題
- 7.5.6 WebView處理網頁返回的錯誤碼信息
- 7.6.1 Socket學習網絡基礎準備
- 7.6.2 基于TCP協議的Socket通信(1)
- 7.6.3 基于TCP協議的Socket通信(2)
- 7.6.4 基于UDP協議的Socket通信
- 8.1.1 Android中的13種Drawable小結 Part 1
- 8.1.2 Android中的13種Drawable小結 Part 2
- 8.1.3 Android中的13種Drawable小結 Part 3
- 8.2.1 Bitmap(位圖)全解析 Part 1
- 8.2.2 Bitmap引起的OOM問題
- 8.3.1 三個繪圖工具類詳解
- 8.3.2 繪圖類實戰示例
- 8.3.3 Paint API之—— MaskFilter(面具)
- 8.3.4 Paint API之—— Xfermode與PorterDuff詳解(一)
- 8.3.5 Paint API之—— Xfermode與PorterDuff詳解(二)
- 8.3.6 Paint API之—— Xfermode與PorterDuff詳解(三)
- 8.3.7 Paint API之—— Xfermode與PorterDuff詳解(四)
- 8.3.8 Paint API之—— Xfermode與PorterDuff詳解(五)
- 8.3.9 Paint API之—— ColorFilter(顏色過濾器)(1/3)
- 8.3.10 Paint API之—— ColorFilter(顏色過濾器)(2-3)
- 8.3.11 Paint API之—— ColorFilter(顏色過濾器)(3-3)
- 8.3.12 Paint API之—— PathEffect(路徑效果)
- 8.3.13 Paint API之—— Shader(圖像渲染)
- 8.3.14 Paint幾個枚舉/常量值以及ShadowLayer陰影效果
- 8.3.15 Paint API之——Typeface(字型)
- 8.3.16 Canvas API詳解(Part 1)
- 8.3.17 Canvas API詳解(Part 2)剪切方法合集
- 8.3.18 Canvas API詳解(Part 3)Matrix和drawBitmapMash
- 8.4.1 Android動畫合集之幀動畫
- 8.4.2 Android動畫合集之補間動畫
- 8.4.3 Android動畫合集之屬性動畫-初見
- 8.4.4 Android動畫合集之屬性動畫-又見
- 9.1 使用SoundPool播放音效(Duang~)
- 9.2 MediaPlayer播放音頻與視頻
- 9.3 使用Camera拍照
- 9.4 使用MediaRecord錄音
- 10.1 TelephonyManager(電話管理器)
- 10.2 SmsManager(短信管理器)
- 10.3 AudioManager(音頻管理器)
- 10.4 Vibrator(振動器)
- 10.5 AlarmManager(鬧鐘服務)
- 10.6 PowerManager(電源服務)
- 10.7 WindowManager(窗口管理服務)
- 10.8 LayoutInflater(布局服務)
- 10.9 WallpaperManager(壁紙管理器)
- 10.10 傳感器專題(1)——相關介紹
- 10.11 傳感器專題(2)——方向傳感器
- 10.12 傳感器專題(3)——加速度/陀螺儀傳感器
- 10.12 傳感器專題(4)——其他傳感器了解
- 10.14 Android GPS初涉
- 11.0《2015最新Android基礎入門教程》完結散花~