Android系統中列表形式的顯示方式應該是我們最熟悉不過的界面了,例如通訊錄、通話記錄、信息列表等等,例如下面的形式:
我們在開發項目需要用到這種形式顯示信息時除了調用系統給我們提供的ListView控件以外我們還可以自定義該控件,因為,如果當需要顯示復雜的顯示列表時系統提供的這種控件不一定能滿足我們的需求,在大多數情況下我們可以自定義此控件。
今天給將介紹三種使用ListView的形式:
首先在窗體中添加ListView控件,在代碼程序執行時對控件進行初始化:
private ListView list_show; list_show = (ListView) this.findViewById(R.id.list_show);
1. SimpleAdapter適配器:
1 SimpleAdapter spa = new SimpleAdapter(this, data, R.layout.list_item, 2 new String[]{"name","age","id"}, new int[]{R.id.name,R.id.age,R.id.id});
他需要的參數包括:
1.當前上下文對象 Context context,
2.數據資源 List<? extends Map<String, ?>> data,
3. 資源布局文件 int resource,
4.String類型數組的List中數據源數據集合 String[] from,
5.資源文件中控件的id集合 int[] to
在上面代碼初始化中我們需要的參數:
List<HashMap<String ,Object>> data = new ArrayList<HashMap<String , Object>>(); for(Student stu : students){ HashMap<String , Object> item = new HashMap<String , Object>(); item.put("name", stu.getName()); item.put("age", stu.getAge()); item.put("id", stu.getId()); data.add(item); }
在此我們需要的數據類型還是上篇代碼中的Student類。
我們已經假設students是一個List<Student>類型的集合,在代碼中我是通過從SQLite數據庫中讀取的。經過迭代可以獲取到其中的值,最后得到值的集合放入到List<HashMap<String,Object>>中。
第三個參數是資源布局文件,也就是我們寫的xml布局文件
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="fill_parent" 4 android:orientation="horizontal" > 5 6 <TextView 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:id="@+id/name" 10 android:paddingLeft="50px" 11 /> 12 13 <TextView 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:id="@+id/age"
18 android:paddingLeft="50px" 19 /> 20 21 22 23 24 <TextView 25 android:id="@+id/id" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:paddingLeft="50px" /> 29 30 </LinearLayout>
最后,設置ListView的適配器:
list_show.setAdapter(spa);
由於界面比較難看,因此在此就不截圖給大家展示了,完整的程序已經打包在此共大家下載。
2. SimpleCursorAdapter適配器:
這個適配器與前面那個在名字上即可知道差別,即這個多了一個Cursor,它的數據來源是Cursor類型的:
cursor是從數據庫中查詢出來的Cursor集合,注意在此不管Cursor數據源來自那兒它都不能被關閉,因為如果cursor.close()以后此對象就不存在,我們也就不能從中讀取數據了。
其他參數可以參考上面第一個或IDE中的提示,用法和第一個一樣。
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, new String[]{"name","age","id"}, new int[]{R.id.name,R.id.age,R.id.id});
最后要記得設置ListView的適配器顯示。
3.自定義適配器:
首先需要建立一個適配器類,這個類繼承BaseAdapter,他會給我們生成必須的一些實現方法:
具體在下面代碼中都已經注釋清楚:
1 package com.example.adapter; 2 3 import java.util.List; 4 5 import com.example.sqllite.R; 6 import com.example.sqllite.Student; 7 8 import android.content.Context; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.BaseAdapter; 13 import android.widget.TextView; 14 15 public class StudentAdapter extends BaseAdapter { 16 17 private List<Student> students; //綁定的數據集 18 private int source; //資源文件 19 private LayoutInflater inflater; //布局填充器,Android的內置服務,作用:使用xml文件來生成對應的view對象 20 21 public StudentAdapter(Context context,List<Student> students , int source){ 22 this.students = students; 23 this.source = source; 24 //得到布局填充服務 25 inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 26 } 27 28 public int getCount() { 29 // TODO Auto-generated method stub 30 return students.size(); 31 } 32 33 public Object getItem(int arg0) { 34 // TODO Auto-generated method stub 35 return students.get(arg0); 36 } 37 38 public long getItemId(int arg0) { 39 // TODO Auto-generated method stub 40 return arg0; 41 } 42 43 //取得代表條目的view對象 44 /* (non-Javadoc) 45 * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) 46 * arg0 當前條目所要綁定的數據在條目中的索引值 47 * 48 */ 49 public View getView(int arg0, View arg1, ViewGroup arg2) { 50 51 TextView idview = null; 52 TextView nameview = null; 53 TextView ageview = null; 54 55 // TODO Auto-generated method stub 56 //判斷是否為第一頁 57 //提供緩存機制 58 if(arg1 == null){ 59 //為條目創建View對象,生成條目界面對象 60 arg1 = inflater.inflate(source, null); 61 62 //得到當前條目的數據 63 idview = (TextView)arg1.findViewById(R.id.id); 64 nameview = (TextView)arg1.findViewById(R.id.name); 65 ageview = (TextView)arg1.findViewById(R.id.age); 66 67 ViewCache cache = new ViewCache(); 68 69 cache.id = idview; 70 cache.name = nameview; 71 cache.age = ageview; 72 73 //用視圖標識臨時存放緩存數據 74 arg1.setTag(cache); 75 } 76 else{ 77 ViewCache cache = (ViewCache)arg1.getTag(); 78 idview = cache.id; 79 nameview = cache.name; 80 ageview = cache.age; 81 } 82 83 //得到當前條目對象 84 Student stu = students.get(arg0); 85 86 //為當前條目賦值 87 idview.setText(stu.getId().toString()); 88 nameview.setText(stu.getName().toString()); 89 ageview.setText(stu.getAge().toString()); 90 91 return arg1; 92 } 93 94 private final class ViewCache{ 95 public TextView id; 96 public TextView name; 97 public TextView age; 98 } 99 100 }
不過在此有一點需要注意,我們用到了緩存,即ListView顯示如果超過一整屏幕后出現下拉列表供我們往下拖動查看更多數據,但是它不會每次都生成一個界面View對象,從很大程度上減少了系統開銷。關於緩存的使用大家可以查閱更多資料來了解。
編寫完了適配器我們就可以使用自定義的適配器來設計我們的ListView的適配器了:
List<Student> students = dbserver.page(0, 15); //從數據庫讀取數據源 StudentAdapter adapter = new StudentAdapter(this.getApplicationContext(), students, R.layout.list_item); list_show.setAdapter(adapter);
自此,已經可以使用我們自定義的適配器來設計我們的ListView了。
此外,我們通常會編寫事件來響應ListView的點擊事件,注意是ListView中Item的點擊事件,ListView控件其本身也有Click事件:
//綁定條目點擊事件 list_show.setOnItemClickListener(new list_listener());
private final class list_listener implements OnItemClickListener{ /* (non-Javadoc) * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long) * arg0 ListView對象 * arg1 當前所點擊的VIew對象 * arg2 當前所點擊的條目所綁定的數據在集合中的索引值 * arg3 當前界面中的排列值 */ public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub //自定義適配器 ListView lView = (ListView)arg0; Student stu = (Student)lView.getItemAtPosition(arg2); //取得arg2索引對應的條目 Toast.makeText(getApplicationContext(), stu.getId().toString(), 1).show(); /*//利用SimpleCursorAdapter得到的是Cursor對象 Cursor cursor = (Cursor) lView.getItemAtPosition(arg2); int id = cursor.getColumnIndex("_id");*/ } }
為了展示最后我們是成功的,不得不把自己設計的奇臭無比的界面獻丑一下:
自此,ListVIew的三種顯示數據形式已經完成,大部分時候系統提供的ListView適配器並不能滿足我們的需求,我們可以使用自定義的適配器來完成我們的項目。