OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / java / android / app / ListActivity.java
1 /*
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
17 package android.app;
18
19 import android.os.Bundle;
20 import android.os.Handler;
21 import android.view.View;
22 import android.widget.AdapterView;
23 import android.widget.ListAdapter;
24 import 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
46  * id "android:empty". Note that when an empty view is present, the list view
47  * 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>
52  *
53  * <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;
57  *         android:layout_width=&quot;match_parent&quot;
58  *         android:layout_height=&quot;match_parent&quot;
59  *         android:paddingLeft=&quot;8dp&quot;
60  *         android:paddingRight=&quot;8dp&quot;&gt;
61  *
62  *     &lt;ListView android:id=&quot;@id/android:list&quot;
63  *               android:layout_width=&quot;match_parent&quot;
64  *               android:layout_height=&quot;match_parent&quot;
65  *               android:background=&quot;#00FF00&quot;
66  *               android:layout_weight=&quot;1&quot;
67  *               android:drawSelectorOnTop=&quot;false&quot;/&gt;
68  *
69  *     &lt;TextView android:id=&quot;@id/android:empty&quot;
70  *               android:layout_width=&quot;match_parent&quot;
71  *               android:layout_height=&quot;match_parent&quot;
72  *               android:background=&quot;#FF0000&quot;
73  *               android:text=&quot;No data&quot;/&gt;
74  * &lt;/LinearLayout&gt;
75  * </pre>
76  *
77  * <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>
97  *
98  * <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"
101  *     android:layout_width=&quot;match_parent&quot;
102  *     android:layout_height=&quot;wrap_content&quot;
103  *     android:orientation=&quot;vertical&quot;&gt;
104  *
105  *     &lt;TextView android:id=&quot;@+id/text1&quot;
106  *         android:textSize=&quot;16sp&quot;
107  *         android:textStyle=&quot;bold&quot;
108  *         android:layout_width=&quot;match_parent&quot;
109  *         android:layout_height=&quot;wrap_content&quot;/&gt;
110  *
111  *     &lt;TextView android:id=&quot;@+id/text2&quot;
112  *         android:textSize=&quot;16sp&quot;
113  *         android:layout_width=&quot;match_parent&quot;
114  *         android:layout_height=&quot;wrap_content&quot;/&gt;
115  * &lt;/LinearLayout&gt;
116  * </pre>
117  *
118  * <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>
138  *
139  * <pre>
140  * public class MyListAdapter extends ListActivity {
141  *
142  *     &#064;Override
143  *     protected void onCreate(Bundle savedInstanceState){
144  *         super.onCreate(savedInstanceState);
145  *
146  *         // 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);
149  *
150  *         // 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.
153  *         mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, null);
154  *         startManagingCursor(mCursor);
155  *
156  *         // Now create a new list adapter bound to the cursor.
157  *         // SimpleListAdapter is designed for binding to a Cursor.
158  *         ListAdapter adapter = new SimpleCursorAdapter(
159  *                 this, // Context.
160  *                 android.R.layout.two_line_list_item,  // Specify the row template to use (here, two columns bound to the two retrieved cursor
161  * rows).
162  *                 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.
165  *
166  *         // Bind to our new adapter.
167  *         setListAdapter(adapter);
168  *     }
169  * }
170  * </pre>
171  *
172  * @see #setListAdapter
173  * @see android.widget.ListView
174  */
175 public 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     };
195
196     /**
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.
201      *
202      * @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     }
209
210     /**
211      * Ensures the list view has been created before Activity restores all
212      * of the view states.
213      *
214      *@see Activity#onRestoreInstanceState(Bundle)
215      */
216     @Override
217     protected void onRestoreInstanceState(Bundle state) {
218         ensureList();
219         super.onRestoreInstanceState(state);
220     }
221
222     /**
223      * @see Activity#onDestroy()
224      */
225     @Override
226     protected void onDestroy() {
227         mHandler.removeCallbacks(mRequestFocus);
228         super.onDestroy();
229     }
230
231     /**
232      * Updates the screen state (current list and other views) when the
233      * content changes.
234      *
235      * @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
272      *
273      * @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     }
300
301     /**
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         }
312         setContentView(com.android.internal.R.layout.list_content);
313
314     }
315
316     private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
317         public void onItemClick(AdapterView<?> parent, View v, int position, long id)
318         {
319             onListItemClick((ListView)parent, v, position, id);
320         }
321     };
322 }