- public class
- ListActivity
- extends Activity
-
- java.lang.Object
- android.content.Context
- android.content.ContextWrapper
- android.view.ContextThemeWrapper
- android.app.Activity
- android.app.ListActivity
Class Overview
ListActivity顯示一個綁定到數組或游標這些數據源的一個列表,並且列表的每一項提供一個點擊事件的管理方法,當用戶點擊其中的列表項的時候就能進行相應的處理。
ListActivity容納了一個ListView對象,這個對象能夠綁定不同的數據源,一般是一個數組或者存儲了一組查詢結果的游標(Cursor)。
屏幕布局
ListActivity的默認布局由一個位於屏幕中心的全屏列表構成。但是,如果你不想使用默認的布局,可以在onCreate()方法中通過setContentView()方法設定你自己定制的布局。
如果指定你自己定制的布局,你的布局中必須包含一個id為"@android:id/list"的ListView 。此外,你自定義的view為空時,能夠包含另外一個任何類型的view對象。
沒有數據(empty list)時,會顯示一個TextView中的數據,而ListView視圖就會被隱藏,但這個TextView的id必須="android:empty"。
下面的代碼示例一個丑陋的自定義屏幕布局。這個布局有一個list,這個list有綠色的背景色,還有一個用來代替的紅色的“no data”消息。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="8dp"
- android:paddingRight="8dp">
-
- <ListView android:id="@id/android:list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#00FF00"
- android:layout_weight="1"
- android:drawSelectorOnTop="false"/>
-
- <TextView id="@id/android:empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#FF0000"
- android:text="No data"/>
- </LinearLayout>
總結:使用ListActivity的目的就是讓其幫我管理ListView等等,所以即使是用我們自己的layout時,其名稱也要用@id/android:list,@id/android:empty來命名,這樣就可以交給ListActivity來管理。
行布局(Row Layout)
你能夠指定列表中一個單獨的行的布局。只要在ListAdapter對象中指定一個布局資源就可以了。ListAdapter綁定數據到ListView。
一個ListAdapter構造函數有一個參數來指定每一行的布局資源。此外,它還有另外兩個參數來指定哪一個數據域與行布局資源中的對象相關聯。這兩個參數一般是平行數組。
Android 提供了一些標准的布局資源。這些都在R.layout類中,名字諸如simple_list_item_1, simple_list_item_2, 和two_line_list_item. 下面的布局XML是two_line_list_item, 對於每一行,它分兩行來表示數據,一個在上一個在下。
<?xml version=
"1.0" encoding=
"utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView android:id="@+id/text1"
- android:textSize="16sp"
- android:textStyle="bold"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- <TextView android:id="@+id/text2"
- android:textSize="16sp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </LinearLayout>
你必須確定綁定到這個布局的每一個TextView對象的數據。下一節就做這一方面的介紹。
綁定數據
綁定ListActivity的ListView對象和數據,要使用一個實現了ListAdapter接口的類。Android提供了兩個標准的list adapters:綁定靜態數據(Maps)的SimpleAdapter,和綁定Cursor的SimpleCursorAdapter。
下面這個例子實例一個自定義的ListActivity,它查詢Contacts provider的所有contacts,然後綁定Name和Company兩個域到ListActivity的ListView中的分為兩行的一個列表項。
public class MyListAdapter
extends ListActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- // We'll define a custom screen layout here (the one shown above), but
- // typically, you could just use the standard ListActivity layout.
- setContentView(R.layout.custom_list_activity_view);
- // Query for all people contacts using the Contacts.People convenience class.
- // Put a managed wrapper around the retrieved cursor so we don't have to worry about
- // requerying or closing it as the activity changes state.
- mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, null);
- startManagingCursor(mCursor);
- // Now create a new list adapter bound to the cursor.
- // SimpleListAdapter is designed for binding to a Cursor.
- ListAdapter adapter = new SimpleCursorAdapter(
- this, // Context.
- android.R.layout.two_line_list_item,
- // Specify the row template to use (here, two columns bound to the two retrieved cursor rows).
- mCursor,
- // Pass in the cursor to bind to.
- new String[] {People.NAME, People.COMPANY},
- // Array of cursor columns to bind to.
- new int[] {android.R.id.text1, android.R.id.text2});
- // Parallel array of which template objects to bind to those columns.
- // Bind to our new adapter.
- setListAdapter(adapter);
- }
- }
還有一種綁定數據的方法
CursorAdapter有兩個子類SimpleCursorAdapter,ResourceCursorAdapter(抽象類)。在CursorAdapter中有兩個方法:newView()和bindView()方法,newView方法用來new一個RowLayout,bindView方法用來向這個新的RowLayout綁定數據。有人會說,這不是太麻煩了嗎,有這個必要嗎?當然有必要啊,因為有些數據不能用SimpleCursorAdapter來進行綁定的。
private final class ContactListItemAdapter
extends ResourceCursorAdapter {
- public ContactListItemAdapter(Context context, int layout, Cursor c) {
- super(context, layout, c);
- }
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- final ContactListItemCache cache = (ContactListItemCache) view.getTag();
- TextView nameView = cache.nameView;
- QuickContactBadge photoView = cache.photoView;
- cursor.copyStringToBuffer(SUMMARY_NAME_COLUMN_INDEX, cache.nameBuffer);
- int size = cache.nameBuffer.sizeCopied;
- nameView.setText(cache.nameBuffer.data, 0, size);
- final long contactId = cursor.getLong(SUMMARY_ID_COLUMN_INDEX);
- final String lookupKey = cursor.getString(SUMMARY_LOOKUP_KEY);
- photoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
- }
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view = super.newView(context, cursor, parent);
- ContactListItemCache cache = new ContactListItemCache();
- cache.nameView = (TextView) view.findViewById(R.id.name);
- cache.photoView = (QuickContactBadge) view.findViewById(R.id.badge);
- view.setTag(cache);
-
- return view;
- }
- }
注意點
其中的view.setTag()方法的主要作用是將數據保存到view對象中,這樣從另外一個方法或另一個線程中,就可以得到其中的數據,這比用全局變量要好很多,可以訪止多線程的情況下,數據的並發訪問。