一、寫在前面:
本次我們來講解一下Android應用中三個適配器:BaseAdapter、SimpleAdapter和ArrayAdapter。其中常見的是BaseAdapter,也是個人推薦使用的適配器。
二、深入了解:
1.什么是適配器?
適配器:在安卓中,顧名思義就是把數據變成符合界面風格的形式,並且通過ListView顯示出來。也就是說適配器是數據和界面之間的橋梁。
適配器在數據庫中的數據(后台)和顯示頁面(前端)中充當一個轉換器的角色,數據庫中的數據(如數組,鏈表,數據庫,集合等)通過適配器變成類手機頁面能夠正常顯示的數據。可以看作是界面數據綁定的一種理解。假設把數據、適配器和ListView(頁面)比喻成一個MVC模式的話,那么適配器(Adapter)在這中間就充當了Controller的角色。
2.為什么對象設置數據源
一般是為ListView提供數據的轉換,當然GridView[網格視圖]、Spinner[下拉列表]、Gallery[畫廊]、ViewPage等都需要使用適配器來為其設置數據源。
三、代碼示例:
ArrayAdapter示范:
要求:使用數組適配器輸出相對應的數據到ListView中
1、首先、創建Android工程,后在布局文件中定義一個ListView,並且設置好相關屬性:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" >
<ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content"/>
</RelativeLayout>
2、其次、在activity類中書寫代碼,具體請看代碼,並且代碼上有相關的注釋
package com.mqz.android_arrayadapter; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { private ListView listView; //定義ListView用來獲取到,布局文件中的ListView控件
private String[] city = {"廣州","深圳","北京","上海","香港","澳門","天津"} ; //定義一個數組,作為數據源
private ArrayAdapter<String> arrayAdapter; //定義一個數組適配器對象
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView)findViewById(R.id.listView); //獲取布局文件中的ListView控件對象
/* * Context context, 上下文對象 * int resource, items項顯示的布局樣式,一般是系統的布局文 android.R.layout.** (但是需要選擇和ListView相適合的布局文件否則運行報錯) * String[] objects 數組對象(數據源) * * */
//創建數組適配器對象,並且通過參數設置類item項的布局樣式和數據源
arrayAdapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1, city); //把數組適配器加載到ListView控件中
listView.setAdapter(arrayAdapter); } }
3、運行結果:這樣不需要我們自己定義TextView控件中的內容,通過數組適配器實現了這一個目的。
SimpleAdapter示范:
要求:把后台數據填充到頁面,其中包括需要填充的有TextView和ImageView,也就是名字和圖片顯示到頁面上。
1、首先,創建好android工程,並且在主布局文件中添加一個ListView控件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context="com.mqz.android_simpleadapter.MainActivity" >
<ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent"
></ListView>
</LinearLayout>
2、其次,在Activity類中書寫代碼,其間附有注釋,具體如下:
package com.mqz.android_simpleadapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private ListView listView; //定義ListView對象,用來獲取布局文件中的ListView控件
private String[] name = {"小明","小華","小梁","小王","小林","小趙"}; //定義一個名字數組,用來為數據源提供姓名
private int[] images = {R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.five,R.drawable.six};//定義一個 整形數組,用來為數據源中的頭像
private List<Map<String,Object>> list_map = new ArrayList<Map<String,Object>>(); //定義一個適配器對象
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView); //獲取布局文件中的ListView對象 //1.准備好數據源,循環為listView添加數據(數據源的准備工作,這里是模擬從SQLite中查詢數據)
for(int i=0;i<6;i++){ Map<String,Object> items = new HashMap<String, Object>(); //創建一個鍵值對的Map集合,用來存放名字和頭像
items.put("pic", images[i]); //放入頭像, 根據下標獲取數組
items.put("name", name[i]); //放入名字, 根據下標獲取數組
list_map.add(items); //把這個存放好數據的Map集合放入到list中,這就完成類數據源的准備工作
} //2、創建適配器(可以使用外部類的方式、內部類方式等均可)
SimpleAdapter simpleAdapter = new SimpleAdapter( MainActivity.this,/*傳入一個上下文作為參數*/ list_map, /*傳入相對應的數據源,這個數據源不僅僅是數據而且還是和界面相耦合的混合體。*/ R.layout.list_items, /*設置具體某個items的布局,需要是新的布局,而不是ListView控件的布局*/
new String[]{"pic","name"}, /*傳入上面定義的鍵值對的鍵名稱,會自動根據傳入的鍵找到對應的值*/
new int[]{R.id.items_imageView1,R.id.items_textView1});/*傳入items布局文件中需要指定傳入的控件,這里直接上id即可*/
//3、為listView加入適配器
listView.setAdapter(simpleAdapter); }); } }
詳細的解釋適配中的參數關系:
3、創建 item 項的 layout 布局文件:
下面是 item 項的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" >
<ImageView android:id="@+id/items_imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content"
/>
<TextView android:id="@+id/items_textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="52dp"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/items_textView2" android:text="hello android!" android:layout_alignParentRight="true"
/>
</RelativeLayout>
4、運行結果:
BaseAdapter示范:
1、創建好安卓工程之后,新建一個包,並且子這個包中定義一個 User 實體類(用來后面的數據源使用),可以簡單定義一兩個屬性即可,這里只是做測試而已。(模擬從數據庫中查詢數據。)
2、在 MainActivity 類中進行主要的代碼書寫:
package com.mqz.android_baseadapter_one; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.mqz.android_baseAdapter_one_entity.User; public class MainActivity extends Activity { private ListView listView; //定義ListView控件,用來獲取布局文件中的ListView
private List<User> list; //存放數據源你的集合,泛型設置為User類型。
private int[] images = {R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.five,};//定義數組,保存圖片Id用用來設置頭像
private String[] names = {"張三","李四","王五","趙六","天啟"};//定義字符串數組,用來保存用戶的名字
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView);//獲取ListView控件 //1.加載數據源,在這里只是模擬一個從數據庫中查詢數據的操作。(模擬數據庫查詢數據的操作)
list = new ArrayList<User>(); for(int i=0;i<5;i++){ User u = new User(); u.setName(names[i]); //設置名字,根據定義的數組設置
u.setPic(images[i]); //定義頭像,在實體類中需要定義為整形,因為在R文件中所有的資源文件都是整形的。
list.add(u); //添加對象到list集合中,數據源准備成功。
} //2.創建BaseAdapter適配器,並且配置好相對應的布局文件(本次使用內部類的方式) //3.把適配器加載到ListView中
MyBaseAdapter adapter = new MyBaseAdapter(); //創建這個成員內部類的對象
listView.setAdapter(adapter); //為數據源設置好適配器
} class MyBaseAdapter extends BaseAdapter{ //獲取當前items項的大小,也可以看成是數據源的大小
@Override public int getCount() { return list.size(); } //根據item的下標獲取到View對象
@Override public Object getItem(int position) { // TODO Auto-generated method stub
return null; } //獲取到items的id
@Override public long getItemId(int position) { // TODO Auto-generated method stub
return 0; } //根據傳入item的下標,獲取到view對象
/* * int position, 表示item所在listView中的下標,也是在數據源中下標所對應的數據 * View convertView, 緩存機制,當一些item項滑出屏幕的時候,會創建新的View對象,這樣會使得內存資源占據, * 所以使用convertView判斷是否為空,如果為空的說明item沒有滑出,需要創建新的view對象 * 如果不為空,說明已經滑出類屏幕所以使用convertView ,view = convertView, * 可以把convert 理解為滑出的view對象 * ViewGroup parent 視圖組對象,即 表示當前繪制的items項所屬的ListView對象。 * */ @Override public View getView(int position, View convertView, ViewGroup parent) { View view = null; //獲取填充器對象,這個對象可以幫助我們繪制出items項,獲取方式有多種: //LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater inflater = MainActivity.this.getLayoutInflater(); /* 調用打氣筒中的 inflate(int resource, ViewGroup root) 方法 第一個參數是一個布局文件對象,通過這個布局文件,inflater會在這布局文件中繪制items項 第二個參數是需不需要將第一個參數中的那個布局文件嵌入到另外一個布局文件中。如果要寫上布局文件的id,如果不需要直接寫null */ view = inflater.inflate(R.layout.items_layout, null); User u = list.get(position);//通過回調這個方法傳過來的position參數獲取到指定數據源中的對象 //找到布局文件中的控件
ImageView pic = (ImageView) view.findViewById(R.id.items_pic); TextView name = (TextView) view.findViewById(R.id.itmes_name); pic.setImageResource(u.getPic());//從數據源中獲取頭像 設置到布局文件的ImageView控件中。
name.setText(u.getName());//從數據源中獲取名字 設置到布局文件的TextView控件中。
return view; } } }
更進一步:
4、運行結果: