列表視圖(ListView)和ListActivity
AdapterView
組件是一組重要的組件,AdapterView
本身是一個抽象基類,它派生的子類
在用法上十分相似,只是顯示界面有一定的區別,因此本節把它們歸為一類,針對它們的共性集中講解,並突出介紹它們的區別。AdapterView
如下特征。
AdapterView
繼承了ViewGroup.它的本質是容器。AdapterView
可以包括多個“列表項”,並將多個“列表項”以合適的形式顯示出來。AdapterView
顯示的多個“列表項”由Adapter提供。調用AdapterView的setAdapter(Adapter)
方法設置Adapter即可。
AdapterView及其子類的繼承關系圖
ListView是手機系統中使用非常廣泛的一種組件,它以垂直列表的形式顯示所有列表項。
創建ListView有如下兩種方式。
- 直接使用ListView進行創建。
- 讓Activity繼承ListActivity(相當於該ActivityM示的組件為ListView)。
一旦在程序中獲得了ListView之后,接下來就需要為ListView設置它要思示的列表項了。在這一點上,ListView表顯示出AdapterView的特征:通過setAdapter(Adapte)方法為之提供Adapter、並由Adapter提供列表項即可。
ListView、GridView.Spinner,Gallery等AdapterView都只是容器,而Adapter負責提供每個“列表項”組件,AdapterView則負責采用合適的方式顯示這些列表項。
# AbsListView常用XML屬性
XML屬性 相關方法 說明
android:choiceMode 設置AbsListView的選擇行為。該屬性支持如下屬性值。
none:不顯示任何選中項
singleChoice:允許單選
multipleChoice:允許多選
multipleChoiceModal:允許多選android:drawSelectorOnTop setDrawSelectorOnTop(boolean) 如果該屬性設為true,選中的列表項將會顯示在上面
android:fastScrollEnabled 設置是否允許快速滾動。如果該屬性設為true,將會顯示滾動圖標,並允許用戶拖動該滾動圖標進行快速滾動
android:listSelector setSelector(int) 指定被選中的列表項上繪制的Drawable
android:scrollingCache 如果設為true,該組件在滾動時將會使用繪制緩存
android:smoothScrollbar setSmoothScrollbarEnabled(boolean) 如果設置為false,則不在header View之后繪制分割線
android:stackFromBottom 設置是否從底端開始排列列表項
android:textFilterEnabled 設置是否對列表項進行過濾。當該AbsListView對應的Adapter實現了Filter接口時該屬性才會起作用
android:transcriptMode 設置該組件的滾動模式。該屬性支持如下屬性值。
disable:關閉滾動。這是默認值normal:當該AbsListView受到數據改變通知,且最后一個列表項可見時,該AbsListView將會滾動到底端
alwaysScroll:該AbsListView總會自動滾動到底端
# ListView常用XML屬性
XML屬性 說明
android:divider 設置List列表項的分隔條(即可用顏色分隔,也可用Drawable分隔)
android:dividerHeight 設置分隔條的高度
android:entries 指定一個數組資源,Android將根據該數組資源來生成ListView
android:footerDividersEnabled 如果設置為false,則不在footer View之前繪制分隔條
android:headerDividersEnabled 如果設置為false,則不在header View之后繪制分隔條
實例:改變分隔條、基於數組的ListView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- 直接使用數組資源給出列表項 --> <!-- 設置使用紅色的分隔條 --> <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" android:entries="@array/books" android:divider="#f00" android:dividerHeight="2px" android:headerDividersEnabled="false"/> </LinearLayout>
上面的界面布局中定義了一個ListView, 並通過android:entries指定了列表項數組,該ListView還通過android:divider
改變了列表項之間的分隔條。
上面第一個ListView指定了android:entries="@array/books"
,該屬性值用到了數組資源,因此還需要在應用中定義一個名為books的數組,定義數組的資源文件如下:
<?xml version="1.0" encoding="UTF-8"?> <resources> <string-array name="books"> <item>Java</item> <item>Ajax</item> <item>XML</item> <item>Android</item> </string-array> </resources>
Adapter接口及實現類
Adapter
本身只是一個接口,它派生了ListAdapter
和SpinnerAdapter
兩個子接口,其中ListAdapter
為AbsListVlew
提供列表項,而SpinnerAdapter
為AbsSpinner
提供列表項。
Adapter及其子類的繼承關系圖
#Adapter
常用的實現類如下。
ArrayAdapter
: 簡單、易用的Adapter。通常用於將數組或List集合的多個值包裝成多個列表項。SimpleAdapter
: 並不簡單、功能強大的Adapter.可用於將List集合的多個對象包裝成多個列表項。SimpleCursorAdapter
: 與SimpleAdapter
基本相似,只是用於包裝Cursor
提供的數據。BaseAdapter
: 通常用於被擴展。擴展BaseAdapter
可以對各列表項進行最大限度的定制。
# 實例:使用 ArrayAdapter創建 ListView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- 設置使用紅色的分隔條 --> <ListView android:id="@+id/list1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:divider="#f00" android:dividerHeight="2px" android:headerDividersEnabled="false" /> <!-- 設置使用綠色的分隔條 --> <ListView android:id="@+id/list2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:divider="#0f0" android:dividerHeight="2px" android:headerDividersEnabled="false" /> </LinearLayout>
上面的布局文件定義了兩個ListView,但這兩個ListView都沒有指定android:entries屬性,這意味着它們都需要通過Adapter來提供列表項。
接下來Activity為兩個ListView提供Adapter,Adapter決定ListView所顯示的列表項。程序如下:
package org.crazyit.ui; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; /** * Description: * <br/>site: <a href="http://www.crazyit.org">crazyit.org</a> * <br/>Copyright (C), 2001-2014, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class ArrayAdapterTest extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView list1 = (ListView) findViewById(R.id.list1); // 定義一個數組 String[] arr1 = { "孫悟空", "豬八戒", "牛魔王" }; // 將數組包裝ArrayAdapter ArrayAdapter<String> adapter1 = new ArrayAdapter<String> (this, R.layout.array_item, arr1); // 為ListView設置Adapter list1.setAdapter(adapter1); ListView list2 = (ListView) findViewById(R.id.list2); // 定義一個數組 String[] arr2 = { "Java", "Hibernate", "Spring" , "Android" }; // 將數組包裝ArrayAdapter ArrayAdapter<String> adapter2 = new ArrayAdapter<String> (this, R.layout.checked_item, arr2); // 為ListView設置Adapter list2.setAdapter(adapter2); } }
通過
ArrayAdapter
實現Adapter
雖然簡單、易用,但ArrayAdapter
的功能比較有限。它的每個列表項只能是TextView
。如果開發者需要實現更復雜的列表項,則可以考慮使用SimpleAdapter
,
不要被SimpleAdapter
的名字欺騙,SimpleAdapter
並不簡單,而且它的功能非常強大。ListView
的大部分應用場景,都可以通過SimpleAdapter
來提供列表項。
自動完成文本框(AutoCompleteTextView)的功能和用法
自動完成文本框(AutoCompleteTextView)從EditText派生而出,實際上它也是一個文本編輯框,但它比普通編輯框多了一個功能:當用戶輸入一定字符之后,自動完成文本框會
顯示一個下拉菜單,供用戶從中選擇,當用戶選擇某個菜單項之后,AutoCompleteTextView按用戶選擇自動填寫該文本框。
網格視圖(GridView)功能和用法
GridView用於在界面h按行、列分布的方式來顯示多個組件。GridView和ListView有共同的父類:AbsListView,因此GridView和ListView具有很高的相似性,它們都是列表項。
GridView與ListView的唯一區別在於:ListView只顯示一列;而GridView可以顯示多列。
從這個角度來看,ListView相當於一種特殊的GridView,如果讓GridView只顯示一列,那么該GridView就變成了ListView。
與ListView類似的是,GridView也需要通過Adapter來提供顯示的數據:開發者可以采用上面介紹的4種方式中的任意一種來創建Adapter。不管使用哪種方式, GridView與ListView的用法是基本一致的。
可展開的列表組件(ExpandableListView)
ExpandableListView是ListView的子類,它在普通LislView的基礎上進行了擴展,它把應用中的列表項分為幾組,每組里又可包含多個列表項。
ExpandableListView的用法與轉通ListView的用法非常相似,只是ExpandableListView所顯示的列表項應該由ExpandableListAdapter提供。
ExpandableListAdapter及其子類的類圖
Spinner的功能和用法
Spinner其實就是一個列表選擇框,不過Android的列表選擇框並不是需要顯示下拉列表的,而是相當於彈出一個菜單供用戶選擇。
Spinner與Gallery都繼承了AbsSpinner,AbsSpinner繼承了AdapterView,因此它也表現出AdapterView的特征:只要為AdapterView提供Adapter即可。
畫廊視圖(Gallery)的功能和用法
Gallery與Spinner組件有共同的父類:AbsSpinner,表明Gallery和Spinner都是一個列表框-它們之間的區別在於Spinner顯示的是一個垂直的列表選擇框,而Gallery顯示的是一個水平的列表選擇框。
Gallery與Spinner還有一個區別:Spinner的作用是供用戶選擇,而Gallery則允許用戶通過拖動來査看上—個、下一個列表項。
Android已經不再推薦使用Gallery組件,而是推薦使用其他水平滾動組件。如HorizontalScrollView和ViewPager來代替Gallery組件。因此在新版本的Android平台上應該盡量少用Gallery組件
AdapterViewFlipper的功能與用法
AdapterViewFilpper繼承了AdapterViewAnimator,它也會顯示Adapter提供的多個View組件,但它每次只能顯示一個View組件,程序可通過showPrevious()和showNext()方法控制該組件顯示上一個、下—個組件。
AdapterViewFilpper可以在多個View切換過程中使用漸隱漸現的動畫效果,除此之外,還可以調用該組件的startFlipping()控制它“自動播放”下一個View組件。
StackView的功能與用法
StackView也是AdapterViewAnimator的子類,它也用於BI2.48使用AdapterViewFlipper顯示Adapter提供的系列View。StackView將會以“堆齎實現自動播放圖片(Stack)”方式來顯示多個列表項,
為了控制StackView顯示的View組件,SlackView提供了如下兩種控制方式。
- 拖走StackView中處於頂端的View,F+-個View將會顯示出來。將上一個View拖進StackView,將使之顯示出來。
- 通過調用StackView的showNext〇、showPrevious〇控制顯示上一個、上一個組件。