Android ListView使用簡介
ListView是Android軟件開發中十分常用也十分重要的一個UI控件。ListView的每一個子項可以是一個簡單的字符串,也可以是一組View的組合,開發者完全可以根據自己的需求來定義顯示的形式。
如何使用一個ListView實現對數據的顯示呢?
1. 創建ListView控件,已備數據顯示
2. 準備要顯示的數據
3. 爲ListView構建一個數據適配器(Adapter)
4. 綁定適配器
5. 處理ListView操作回調,完成業務功能
如何創建ListView?
我們可以直接使用xml格式的佈局(layout)文件來創建一個ListView,如果我們已經有一個佈局(layout)文件,直接添加ListView控件。
<FrameLayout 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"
tools:context=".MainActivity">
<ListView
android:id="@+id/id_listview_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
然後再Activity中去獲取該控件,這樣就可以使用該控件了。
當然,我們也可以直接用代碼創建一個ListView控件,並把該控件作爲要顯示的View,或者添加到現有的一個groupview控件中去。
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ListView myListView = new ListView(this);
setContentView(myListView);
}
一般建議在佈局(layout)文件中進行UI控件的定義。
如何創建一個適配器?
在這幾個步驟中,構建數據適配器是很重要的一個環節,同樣也是比較複雜的一個環節。ListView常用的適配器(Adapter)有以下幾種。
Adapter |
含義 |
ArrayAdapter<T> |
用來綁定一個數組,支持泛型操作 |
SimpleAdapter |
用來綁定在xml中定義的控件對應的數據 |
SimpleCursorAdapter |
用來綁定遊標得到的數據 |
BaseAdapter |
通用的基礎適配器 |
- 使用ArrayAdapter綁定數據
1. 準備數據
private static final String[] strDatas = new String[] {
"first", "second", "third", "fourth", "fifth"
};
2. 直接綁定
ListView lv = (ListView) findViewById(R.id.id_listview_list);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, strDatas));
此處使用了Android系統自帶的一個列表Item樣式,顯示效果如下圖:
使用ArrayAdapter綁定數據適用數據特別簡單的情況。
- 使用SimpleAdapter綁定數據
1.創建列表Item樣式佈局文件(simple_adapter_item.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/sai_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textSize="18dp"
android:layout_weight="1"
android:textColor="#000"
/>
<TextView
android:id="@+id/sai_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18dp"
android:layout_weight="3"
android:textColor="#000"
/>
<TextView
android:id="@+id/sai_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18dp"
android:layout_weight="4"
android:textColor="#000"
/>
</LinearLayout>
2.準備數據
List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
Map<String,Object> map1=new HashMap<String, Object>();
map1.put("id", "001");
map1.put("name", "張三");
map1.put("phone", "13588551201");
Map<String,Object> map2=new HashMap<String, Object>();
map2.put("id", "002");
map2.put("name", "李四");
map2.put("phone", "13588551202");
Map<String,Object> map3=new HashMap<String, Object>();
map3.put("id", "003");
map3.put("name", "張二虎");
map3.put("phone", "13588551203");
Map<String,Object> map4=new HashMap<String, Object>();
map4.put("id", "004");
map4.put("name", "李老大");
map4.put("phone", "13588551204");
Map<String,Object> map5=new HashMap<String, Object>();
map5.put("id", "005");
map5.put("name", "王老二");
map5.put("phone", "13588551205");
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
data.add(map5);
3.綁定適配器
ListView lv = (ListView) findViewById(R.id.id_listview_list);
lv.setAdapter(new SimpleAdapter(this,
data, R.layout.simple_adapter_item,
new String[]{"id","name","phone"},
new int[]{R.id.sai_id,R.id.sai_name, R.id.sai_phone}));
顯示效果如下:
- 使用SimpleCursorAdapter綁定數據
1.此示例中列表Item樣式佈局文件直接複用上個例子中的佈局文件simple_adapter_item.xml。
2.準備數據
一般情況下Cursor都是通過查找數據獲取到的,此處我們的重點是看如何用在SimpleCursorAdapter中來綁定到ListView中,因此我們使用可以直接示例化並可以直接插入數據的MatrixCursor類完成數據提供任務。代碼如下:
String[] tableCursor = new String[] { "_id", "name", "phone" };
MatrixCursor cursor = new MatrixCursor(tableCursor);
cursor.addRow(new Object[]{"100", "張大", "13588551201" });
cursor.addRow(new Object[]{"101", "張二", "13588551202" });
cursor.addRow(new Object[]{"102", "張三", "13588551203" });
cursor.addRow(new Object[]{"103", "張四", "13588551204" });
cursor.addRow(new Object[]{"104", "張五", "13588551205" });
與上一個例子的數據幾乎一樣,有沒有發現,此處簡單了很多呢?哈哈!不過需要注意的是,作爲SimpleCursorAdapter的Cursor必需要有"_id"列,否則會報錯。
3.數據綁定
ListView lv = (ListView)findViewById(R.id.id_simplecursordapter_list);
lv.setAdapter(new SimpleCursorAdapter(this,
R.layout.simple_adapter_item, cursor, tableCursor, new int[]{R.id.sai_id,R.id.sai_name, R.id.sai_phone}));
運行效果如下,是不是和上面一個例子效果一樣啊!
- 使用BaseAdapter綁定數據
OK, 此處其實才是ListView用的最多的適配器實現方式,一般都是通過繼承BaseAdapter類並重寫父類的一些方法來完成ListView數據的綁定。繼承BaseAdapter的類必需實現以下幾個接口函數:
public int getCount(); //獲取適配器中數據集中數據的條目數
public Object getItem(int i);//獲取數據集中與指定索引對應的數據項
public long getItemId(int i);//獲取數據集中指定索引對應的項的id
public View getView(int i, View view, ViewGroup viewGroup);//獲取指定索引的列表Item的view
下面,還是使用與上面兩個例子相同的列表佈局及類似數據來實現列表的數據綁定實現。
1.建立數據類
public class Data {
public Data(String i, String n, String p){
id = i;
name = n;
phone = p;
}
public String id;
public String name;
public String phone;
}
2.繼承BaseAdapter實現我們自己的適配器
public class MyAdapter extends BaseAdapter {
private List<Data> mDatas = null;
private Context mContext = null;
public MyAdapter(Context context, List<Data> datas){
mDatas = datas;
mContext = context;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int i) {
return mDatas.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder vh;
if (view == null){
vh = new ViewHolder();
view = LayoutInflater.from(mContext).inflate(R.layout.simple_adapter_item, null);
vh.id = (TextView)view.findViewById(R.id.sai_id);
vh.name = (TextView)view.findViewById(R.id.sai_name);
vh.phone = (TextView)view.findViewById(R.id.sai_phone);
view.setTag(vh);
} else {
vh = (ViewHolder)view.getTag();
}
vh.id.setText(mDatas.get(i).id);
vh.name.setText(mDatas.get(i).name);
vh.phone.setText(mDatas.get(i).phone);
return view;
}
public final class ViewHolder
{
public TextView id;
public TextView name;
public TextView phone;
}
}
適配其中使用了ViewHolder來提升ListView的繪製效率,通過使用ViewHolder,ListView的Item就可以複用View,而不用每次都去新建一個View。關於此方面知識,可以參考相關文章,此處的示例代碼採用比較常用的實現方式,目的也是讓大家從一開始認識他的時候就建立幾個好的初印象,避免誤導了讀者。
3.準備數據並綁定到ListView
List<Data> datas = new ArrayList<Data>();
Data data1 = new Data("111", "老周1", "13656461200");
Data data2 = new Data("112", "老周2", "13656461201");
Data data3 = new Data("113", "老周3", "13656461202");
Data data4 = new Data("114", "老周4", "13656461203");
Data data5 = new Data("115", "老周5", "13656461204");
Data data6 = new Data("116", "老周6", "13656461205");
datas.add(data1);
datas.add(data2);
datas.add(data3);
datas.add(data4);
datas.add(data5);
datas.add(data6);<pre name="code" class="java">MyAdapter adapter = new MyAdapter(this, datas);
ListView lv = (ListView)findViewById(R.id.id_baseadapter_list);
lv.setAdapter(adapter);
此處數據的獲取略顯笨拙,但在實際的項目中,一般都是從數據庫獲取數據,或者是像文件瀏覽器直接獲取系統文件信息。
顯示效果還是與上面類似的鳥樣:
OK,上面介紹了四種ListView的Adapter來實現ListView的數據綁定,我們來做一個簡單的比較。
ArrayAdapter<T> 適合非常簡單的數據顯示,很方便,很簡單。
SimpleAdapter 可以自定義Item佈局,用於顯示交簡單的佈局及控件,但佈局內的控件如按鈕等無法獲取到焦點,當然也就無法獲取到他們的點擊事件。
SimpleCursorAdapter 與SimpleAdapter相似,只是他的數據源是Cursor類型而已。
BaseAdpter子類 最常用的ListView數據適配器,通過繼承BaseAdpter可以較靈活的實現數據的綁定,同時通過使用ViewHolder等技術可以很好的提高ListView的繪製效率。另一個很重要的原因,BaseAdpter類適配器綁定的Item佈局中的子控件可以獲取到觸摸焦點,也就是說,通過這種方式,我們可以獲取Item佈局中一些對象的點擊,長按,check等方法。