在Android開發中,ListView是比較常用的控件,它以列表的形式顯示具體內容,並且能夠根據數據的長度自適應顯示。 在ListView中可以根據需要顯示自定義的列表內容,包括文字(TextView)、圖片(ImageView)、按鈕(Button)等,以此構成圖文並茂的顯示效果。
在本篇博文中,將使用ListView控件實現簡單的博客園首頁博文條目顯示效果,如圖1所示。

圖1 ListView實例效果圖
1.界面布局
由圖1的ListView實例效果圖可以看出,在該ListView控件中,我們添加了四條列表項,而每一個列表項都是由五部分構成的,分別是:博文題目(TextView)、作者頭像(ImageView)、博文概要(TextView)、作者昵稱(TextView)和發布日期(TextView)。
我們需要自己定義一個xml布局文件,來對ListView控件的列表項進行布局,以符合我們的式樣需求。這里,我定義了一個名為“listviewitem”的xml布局文件,用來對列表項中的五個控件進行布局,其具體內容如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:descendantFocusability="afterDescendants" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical" > 7 8 <!-- 博文題目 --> 9 <TextView 10 android:id="@+id/title" 11 android:layout_marginLeft="5dp" 12 android:layout_marginTop="5dp" 13 android:layout_width="match_parent" 14 android:layout_height="wrap_content" 15 android:textStyle="bold" 16 android:textColor="#0000FF" 17 android:lines="1" > 18 </TextView> 19 20 <!-- 作者頭像和博文概要 --> 21 <LinearLayout 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 android:layout_marginTop="2dp" 25 android:layout_marginLeft="5dp" 26 android:orientation="horizontal" > 27 <ImageView 28 android:id="@+id/photograph" 29 android:layout_marginTop="2dp" 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" ></ImageView> 32 <TextView 33 android:id="@+id/summary" 34 android:layout_marginLeft="2dp" 35 android:layout_width="wrap_content" 36 android:layout_height="wrap_content" 37 android:lines="3" ></TextView> 38 </LinearLayout> 39 40 <!-- 作者昵稱和發布日期 --> 41 <LinearLayout 42 android:layout_width="match_parent" 43 android:layout_height="wrap_content" 44 android:layout_marginLeft="5dp" 45 android:layout_marginTop="2dp" 46 android:layout_marginBottom="2dp" 47 android:orientation="horizontal" > 48 <TextView 49 android:id="@+id/author" 50 android:layout_width="80dp" 51 android:layout_height="wrap_content" 52 android:textColor="#0000FF" ></TextView> 53 <TextView 54 android:id="@+id/publishtime" 55 android:layout_width="wrap_content" 56 android:layout_height="wrap_content" ></TextView> 57 </LinearLayout> 58 59 </LinearLayout>
可以看出,在該布局文件中,使用了LinearLayout的垂直布局方式將每個列表項分成了上中下三部分,上方顯示博文題目,中間則使用LinearLayout的水平布局方式顯示作者頭像和博文概要,下方同樣使用LinearLayout的水平布局方式顯示作者昵稱和發布日期。
2.ListView的xml屬性
ListView的xml屬性如圖2所示。

圖2 ListView的xml屬性
其中,android:divider[Drawable/Color]用於設置相鄰兩個列表項之間的分界線式樣;android:dividerHeight[dimension]用於設置相鄰兩個列表項之間的分界線高度;android:entries[array resource]用於將靜態數組中的內容直接填充到ListView列表中。
根據以上的ListView的xml屬性介紹,我們便可以activity_main.xml布局文件中設置ListView的屬性如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <ListView 8 android:id="@+id/listview" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:divider="@drawable/dividerimage" > 12 </ListView> 13 14 </LinearLayout>
其中,我們設置了相鄰兩個列表項之間的分界線式樣為一根粉色的分界線。
3.數據加載
如何將數據加載到ListView控件的各個列表項中是使用ListView控件的關鍵。
通過查看ListView的API幫助文檔,我們可以找到相關的設置ListView控件的適配器的方法如下:
public void setAdapter (ListAdapter adapter);
不難看出,ListView控件的適配器類型為ListAdapter,而ListAdapter的子類有ArrayAdapter<T>、BaseAdapter、CursorAdapter、HeaderViewListAdapter、SimpleAdapter、ResourceCursorAdapter、SimpleCursorAdapter和WrapperListAdapter,所以我們可以使用SimpleAdapter作為ListView控件的適配器使用。
簡單適配器SimpleAdapter具有良好的可擴充性,可方便的將xml中的控件與所要填充的數據匹配起來。具體實現方法如下:
1 /* 2 * Function : onCreate() 3 * Author : 博客園-依舊淡然 4 */ 5 public void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 9 mListView = (ListView)this.findViewById(R.id.listview); 10 11 //創建簡單適配器SimpleAdapter 12 simpleAdapter = new SimpleAdapter(this, this.getItem(), R.layout.listviewitem, 13 new String[] {"itemTitle","itemPhoto", "itemSummary", "itemAuthor", "itemPublishtime"}, 14 new int[] {R.id.title, R.id.photograph, R.id.summary, R.id.author, R.id.publishtime}); 15 16 //加載SimpleAdapter到ListView中 17 mListView.setAdapter(simpleAdapter); 18 }
在如上的代碼中,用到了自定義的getItem()方法,該方法的作用是獲取所有的列表內容。我們可以使用HashMap來儲存一個列表項中的每一條數據(通過鍵值對的形式),這樣每一個HashMap便儲存了一個列表項的所有信息,然后再將HashMap添加到ArrayList中進行儲存。如此,我們便可以通過使用自定義的getItem()方法來獲取所有的列表內容了。具體的實現方法如下:
1 /* 2 * Function : 獲取所有的列表內容 3 * Author : 博客園-依舊淡然 4 */ 5 public ArrayList<HashMap<String, Object>> getItem() { 6 ArrayList<HashMap<String, Object>> item = new ArrayList<HashMap<String, Object>>(); 7 for (int i = 0; i < ListViewItemData.getItemNum(); i++) { 8 HashMap<String, Object> map = new HashMap<String, Object>(); 9 map.put("itemTitle", ListViewItemData.getTitle(i)); 10 map.put("itemPhoto", ListViewItemData.getPhotoResId(i)); 11 map.put("itemSummary", ListViewItemData.getSummary(i)); 12 map.put("itemAuthor", ListViewItemData.getAuthor(i)); 13 map.put("itemPublishtime", ListViewItemData.getPublishtime(i)); 14 item.add(map); 15 } 16 return item; 17 }
在如上的代碼中,ListViewItemData是自定義的一個類,通過靜態數組的形式儲存了所有列表項中所要顯示的文本和圖片資源。
4.事件監聽
我們可以為ListView控件設置事件監聽器OnItemClickListener,用來對用戶的點擊事件進行監聽,並根據用戶所選列表項的不同進行與之相對應的響應。我們需要實現OnItemClickListener接口中的抽象方法onItemClick(),如下:
public void onItemClick(AdapterView<?> parent, View view, int position, long id);
其中,參數position表示各個列表項在ListView控件中所處的位置,自上往下從0開始算起。在該實例中,當點擊第一個列表項時,將關閉當前的Activity,並打開一個新的Activity,在新的Activity中,我們通過使用WebView控件來載入我的博客首頁,如圖3所示。

圖3 通過WebView控件載入網頁
5.待完善點
在該實例中,只能獲取整個列表項的焦點,並響應整個列表項的點擊事件,如圖4所示。

圖4 ListView控件獲取焦點示例
如何讓每個列表項中的各個子項(比如:博文標題、作者)都可以獲取焦點,並響應點擊事件,將是后續學習和完善的一個方面。
此外,在該實例中,每個列表項中的內容,都是儲存在自定義的ListViewItemData類中的。顯然這是不符合實際開發需求的,正確的做法應當是通過解析來自網絡的JSON(或XML)數據,然后將其填充到ListView控件列表中。所以,如何解析JSON數據也是后續的一個學習方向。
