blob: 2162521edce1916458472330f74dd843164efc9f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.os.Bundle;
20import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.widget.AdapterView;
23import android.widget.ListAdapter;
24import android.widget.ListView;
25
26/**
27 * An activity that displays a list of items by binding to a data source such as
28 * an array or Cursor, and exposes event handlers when the user selects an item.
29 * <p>
30 * ListActivity hosts a {@link android.widget.ListView ListView} object that can
31 * be bound to different data sources, typically either an array or a Cursor
32 * holding query results. Binding, screen layout, and row layout are discussed
33 * in the following sections.
34 * <p>
35 * <strong>Screen Layout</strong>
36 * </p>
37 * <p>
38 * ListActivity has a default layout that consists of a single, full-screen list
39 * in the center of the screen. However, if you desire, you can customize the
40 * screen layout by setting your own view layout with setContentView() in
41 * onCreate(). To do this, your own view MUST contain a ListView object with the
42 * id "@android:id/list" (or {@link android.R.id#list} if it's in code)
43 * <p>
44 * Optionally, your custom view can contain another view object of any type to
45 * display when the list view is empty. This "empty list" notifier must have an
Romain Guyffa33742011-02-22 11:24:15 -080046 * id "android:id/empty". Note that when an empty view is present, the list view
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 * will be hidden when there is no data to display.
48 * <p>
49 * The following code demonstrates an (ugly) custom screen layout. It has a list
50 * with a green background, and an alternate red "no data" message.
51 * </p>
Nicolas Cataniaf767e752010-03-12 15:21:50 -080052 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 * <pre>
54 * &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
55 * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
56 * android:orientation=&quot;vertical&quot;
Nicolas Cataniaf767e752010-03-12 15:21:50 -080057 * android:layout_width=&quot;match_parent&quot;
Romain Guy980a9382010-01-08 15:06:28 -080058 * android:layout_height=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 * android:paddingLeft=&quot;8dp&quot;
60 * android:paddingRight=&quot;8dp&quot;&gt;
Nicolas Cataniaf767e752010-03-12 15:21:50 -080061 *
Romain Guyffa33742011-02-22 11:24:15 -080062 * &lt;ListView android:id=&quot;@android:id/list&quot;
Nicolas Cataniaf767e752010-03-12 15:21:50 -080063 * android:layout_width=&quot;match_parent&quot;
Romain Guy980a9382010-01-08 15:06:28 -080064 * android:layout_height=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 * android:background=&quot;#00FF00&quot;
66 * android:layout_weight=&quot;1&quot;
67 * android:drawSelectorOnTop=&quot;false&quot;/&gt;
Nicolas Cataniaf767e752010-03-12 15:21:50 -080068 *
Romain Guyffa33742011-02-22 11:24:15 -080069 * &lt;TextView android:id=&quot;@android:id/empty&quot;
Nicolas Cataniaf767e752010-03-12 15:21:50 -080070 * android:layout_width=&quot;match_parent&quot;
Romain Guy980a9382010-01-08 15:06:28 -080071 * android:layout_height=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 * android:background=&quot;#FF0000&quot;
73 * android:text=&quot;No data&quot;/&gt;
74 * &lt;/LinearLayout&gt;
75 * </pre>
Nicolas Cataniaf767e752010-03-12 15:21:50 -080076 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 * <p>
78 * <strong>Row Layout</strong>
79 * </p>
80 * <p>
81 * You can specify the layout of individual rows in the list. You do this by
82 * specifying a layout resource in the ListAdapter object hosted by the activity
83 * (the ListAdapter binds the ListView to the data; more on this later).
84 * <p>
85 * A ListAdapter constructor takes a parameter that specifies a layout resource
86 * for each row. It also has two additional parameters that let you specify
87 * which data field to associate with which object in the row layout resource.
88 * These two parameters are typically parallel arrays.
89 * </p>
90 * <p>
91 * Android provides some standard row layout resources. These are in the
92 * {@link android.R.layout} class, and have names such as simple_list_item_1,
93 * simple_list_item_2, and two_line_list_item. The following layout XML is the
94 * source for the resource two_line_list_item, which displays two data
95 * fields,one above the other, for each list row.
96 * </p>
Nicolas Cataniaf767e752010-03-12 15:21:50 -080097 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 * <pre>
99 * &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
100 * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Romain Guy980a9382010-01-08 15:06:28 -0800101 * android:layout_width=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 * android:layout_height=&quot;wrap_content&quot;
103 * android:orientation=&quot;vertical&quot;&gt;
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800104 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 * &lt;TextView android:id=&quot;@+id/text1&quot;
106 * android:textSize=&quot;16sp&quot;
107 * android:textStyle=&quot;bold&quot;
Romain Guy980a9382010-01-08 15:06:28 -0800108 * android:layout_width=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 * android:layout_height=&quot;wrap_content&quot;/&gt;
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800110 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 * &lt;TextView android:id=&quot;@+id/text2&quot;
112 * android:textSize=&quot;16sp&quot;
Romain Guy980a9382010-01-08 15:06:28 -0800113 * android:layout_width=&quot;match_parent&quot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 * android:layout_height=&quot;wrap_content&quot;/&gt;
115 * &lt;/LinearLayout&gt;
116 * </pre>
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800117 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 * <p>
119 * You must identify the data bound to each TextView object in this layout. The
120 * syntax for this is discussed in the next section.
121 * </p>
122 * <p>
123 * <strong>Binding to Data</strong>
124 * </p>
125 * <p>
126 * You bind the ListActivity's ListView object to data using a class that
127 * implements the {@link android.widget.ListAdapter ListAdapter} interface.
128 * Android provides two standard list adapters:
129 * {@link android.widget.SimpleAdapter SimpleAdapter} for static data (Maps),
130 * and {@link android.widget.SimpleCursorAdapter SimpleCursorAdapter} for Cursor
131 * query results.
132 * </p>
133 * <p>
134 * The following code from a custom ListActivity demonstrates querying the
135 * Contacts provider for all contacts, then binding the Name and Company fields
136 * to a two line row layout in the activity's ListView.
137 * </p>
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800138 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 * <pre>
140 * public class MyListAdapter extends ListActivity {
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800141 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 * &#064;Override
143 * protected void onCreate(Bundle savedInstanceState){
144 * super.onCreate(savedInstanceState);
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800145 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 * // We'll define a custom screen layout here (the one shown above), but
147 * // typically, you could just use the standard ListActivity layout.
148 * setContentView(R.layout.custom_list_activity_view);
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800149 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 * // Query for all people contacts using the {@link android.provider.Contacts.People} convenience class.
151 * // Put a managed wrapper around the retrieved cursor so we don't have to worry about
152 * // requerying or closing it as the activity changes state.
Joe LaPennaa01d5fe2009-07-23 15:14:14 -0700153 * mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 * startManagingCursor(mCursor);
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800155 *
156 * // Now create a new list adapter bound to the cursor.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 * // SimpleListAdapter is designed for binding to a Cursor.
158 * ListAdapter adapter = new SimpleCursorAdapter(
159 * this, // Context.
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800160 * android.R.layout.two_line_list_item, // Specify the row template to use (here, two columns bound to the two retrieved cursor
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 * rows).
Joe LaPennaa01d5fe2009-07-23 15:14:14 -0700162 * mCursor, // Pass in the cursor to bind to.
163 * new String[] {People.NAME, People.COMPANY}, // Array of cursor columns to bind to.
164 * new int[] {android.R.id.text1, android.R.id.text2}); // Parallel array of which template objects to bind to those columns.
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800165 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 * // Bind to our new adapter.
167 * setListAdapter(adapter);
168 * }
169 * }
170 * </pre>
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800171 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 * @see #setListAdapter
173 * @see android.widget.ListView
174 */
175public class ListActivity extends Activity {
176 /**
177 * This field should be made private, so it is hidden from the SDK.
178 * {@hide}
179 */
180 protected ListAdapter mAdapter;
181 /**
182 * This field should be made private, so it is hidden from the SDK.
183 * {@hide}
184 */
185 protected ListView mList;
186
187 private Handler mHandler = new Handler();
188 private boolean mFinishedStart = false;
189
190 private Runnable mRequestFocus = new Runnable() {
191 public void run() {
192 mList.focusableViewAvailable(mList);
193 }
194 };
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 /**
197 * This method will be called when an item in the list is selected.
198 * Subclasses should override. Subclasses can call
199 * getListView().getItemAtPosition(position) if they need to access the
200 * data associated with the selected item.
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800201 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 * @param l The ListView where the click happened
203 * @param v The view that was clicked within the ListView
204 * @param position The position of the view in the list
205 * @param id The row id of the item that was clicked
206 */
207 protected void onListItemClick(ListView l, View v, int position, long id) {
208 }
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 /**
211 * Ensures the list view has been created before Activity restores all
212 * of the view states.
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800213 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 *@see Activity#onRestoreInstanceState(Bundle)
215 */
216 @Override
217 protected void onRestoreInstanceState(Bundle state) {
218 ensureList();
219 super.onRestoreInstanceState(state);
220 }
221
222 /**
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800223 * @see Activity#onDestroy()
224 */
225 @Override
226 protected void onDestroy() {
227 mHandler.removeCallbacks(mRequestFocus);
228 super.onDestroy();
229 }
230
231 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 * Updates the screen state (current list and other views) when the
233 * content changes.
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800234 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 * @see Activity#onContentChanged()
236 */
237 @Override
238 public void onContentChanged() {
239 super.onContentChanged();
240 View emptyView = findViewById(com.android.internal.R.id.empty);
241 mList = (ListView)findViewById(com.android.internal.R.id.list);
242 if (mList == null) {
243 throw new RuntimeException(
244 "Your content must have a ListView whose id attribute is " +
245 "'android.R.id.list'");
246 }
247 if (emptyView != null) {
248 mList.setEmptyView(emptyView);
249 }
250 mList.setOnItemClickListener(mOnClickListener);
251 if (mFinishedStart) {
252 setListAdapter(mAdapter);
253 }
254 mHandler.post(mRequestFocus);
255 mFinishedStart = true;
256 }
257
258 /**
259 * Provide the cursor for the list view.
260 */
261 public void setListAdapter(ListAdapter adapter) {
262 synchronized (this) {
263 ensureList();
264 mAdapter = adapter;
265 mList.setAdapter(adapter);
266 }
267 }
268
269 /**
270 * Set the currently selected list item to the specified
271 * position with the adapter's data
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800272 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 * @param position
274 */
275 public void setSelection(int position) {
276 mList.setSelection(position);
277 }
278
279 /**
280 * Get the position of the currently selected list item.
281 */
282 public int getSelectedItemPosition() {
283 return mList.getSelectedItemPosition();
284 }
285
286 /**
287 * Get the cursor row ID of the currently selected list item.
288 */
289 public long getSelectedItemId() {
290 return mList.getSelectedItemId();
291 }
292
293 /**
294 * Get the activity's list view widget.
295 */
296 public ListView getListView() {
297 ensureList();
298 return mList;
299 }
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 /**
302 * Get the ListAdapter associated with this activity's ListView.
303 */
304 public ListAdapter getListAdapter() {
305 return mAdapter;
306 }
307
308 private void ensureList() {
309 if (mList != null) {
310 return;
311 }
Dianne Hackbornef769f62010-07-12 11:40:53 -0700312 setContentView(com.android.internal.R.layout.list_content_simple);
Nicolas Cataniaf767e752010-03-12 15:21:50 -0800313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 }
315
316 private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
Christian Mehlmauerd6c19192010-05-21 19:02:48 +0200317 public void onItemClick(AdapterView<?> parent, View v, int position, long id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 {
319 onListItemClick((ListView)parent, v, position, id);
320 }
321 };
322}