listview.jd revision 50e990c64fa23ce94efa76b9e72df7f8ec3cee6a
1page.title=List View
2parent.title=Layouts
3parent.link=declaring-layout.html
4@jd:body
5<div id="qv-wrapper">
6<div id="qv">
7<h2>In this document</h2>
8  <ol>
9    <li><a href="#Loader">Using a Loader</a></li>
10    <li><a href="#Example">Example</a></li>
11  </ol>
12  <h2>Key classes</h2>
13  <ol>
14    <li>{@link android.widget.ListView}</li>
15    <li>{@link android.widget.Adapter}</li>
16    <li>{@link android.support.v4.content.CursorLoader}</li>
17  </ol>
18  <h2>See also</h2>
19  <ol>
20    <li><a
21href="{@docRoot}guide/components/loaders.html">Loaders</a></li>
22  </ol>
23</div>
24</div>
25
26<p>{@link android.widget.ListView} is a view group that displays a list of
27scrollable items. The list items are automatically inserted to the list using an {@link
28android.widget.Adapter} that pulls content from a source such as an array or database query and
29converts each item result into a view that's placed into the list.</p>
30
31<img src="{@docRoot}images/ui/listview.png" alt="" />
32
33<h2 id="Loader">Using a Loader</h2>
34
35<p>Using a {@link
36android.support.v4.content.CursorLoader} is the standard way to query a {@link
37android.database.Cursor} as an asynchronous task in order to avoid blocking your app's main thread
38with the query. When the {@link android.support.v4.content.CursorLoader} receives the {@link
39android.database.Cursor} result, the {@link android.support.v4.app.LoaderManager.LoaderCallbacks
40LoaderCallbacks} receives a callback to {@link
41android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}, which is
42where you update your {@link
43android.widget.Adapter} with the new {@link android.database.Cursor} and the list view then
44displays the results.</p>
45
46<p>Although the {@link android.support.v4.content.CursorLoader} APIs were first introduced in
47Android 3.0 (API level 11), they are also available in the <a
48href="{@docRoot}tools/extras/support-library.html">Support Library</a> so that your app may use them
49while supporting devices running Android 1.6 or higher.</p>
50
51<p>For more information about using a {@link
52android.support.v4.content.Loader} to asynchronously load data, see the <a
53href="{@docRoot}guide/components/loaders.html">Loaders</a> guide.</p>
54
55
56<h2 id="Example">Example</h2>
57
58<p>The following example uses {@link android.app.ListActivity}, which is an activity that includes
59a {@link android.widget.ListView} as its only layout element by default. It performs a query to
60the <a
61href="{@docRoot}guide/topics/providers/contacts-provider.html">Contacts
62Provider</a> for a list of names and phone numbers.</p>
63
64<p>The activity implements the {@link android.support.v4.app.LoaderManager.LoaderCallbacks
65LoaderCallbacks} interface in order to use a {@link android.support.v4.content.CursorLoader} that
66dynamically loads the data for the list view.</p>
67
68<pre>
69public class ListViewLoader extends ListActivity
70        implements LoaderManager.LoaderCallbacks&lt;Cursor> {
71
72    // This is the Adapter being used to display the list's data
73    SimpleCursorAdapter mAdapter;
74
75    // These are the Contacts rows that we will retrieve
76    static final String[] PROJECTION = new String[] {ContactsContract.Data._ID,
77            ContactsContract.Data.DISPLAY_NAME};
78
79    // This is the select criteria
80    static final String SELECTION = "((" + 
81            ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" +
82            ContactsContract.Data.DISPLAY_NAME + " != '' ))";
83
84    &#64;Override
85    protected void onCreate(Bundle savedInstanceState) {
86        super.onCreate(savedInstanceState);
87
88        // Create a progress bar to display while the list loads
89        ProgressBar progressBar = new ProgressBar(this);
90        progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
91                LayoutParams.WRAP_CONTENT, Gravity.CENTER));
92        progressBar.setIndeterminate(true);
93        getListView().setEmptyView(progressBar);
94
95        // Must add the progress bar to the root of the layout
96        ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
97        root.addView(progressBar);
98
99        // For the cursor adapter, specify which columns go into which views
100        String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
101        int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1
102
103        // Create an empty adapter we will use to display the loaded data.
104        // We pass null for the cursor, then update it in onLoadFinished()
105        mAdapter = new SimpleCursorAdapter(this, 
106                android.R.layout.simple_list_item_1, null,
107                fromColumns, toViews, 0);
108        setListAdapter(mAdapter);
109
110        // Prepare the loader.  Either re-connect with an existing one,
111        // or start a new one.
112        getLoaderManager().initLoader(0, null, this);
113    }
114
115    // Called when a new Loader needs to be created
116    public Loader&lt;Cursor> onCreateLoader(int id, Bundle args) {
117        // Now create and return a CursorLoader that will take care of
118        // creating a Cursor for the data being displayed.
119        return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
120                PROJECTION, SELECTION, null, null);
121    }
122
123    // Called when a previously created loader has finished loading
124    public void onLoadFinished(Loader&lt;Cursor> loader, Cursor data) {
125        // Swap the new cursor in.  (The framework will take care of closing the
126        // old cursor once we return.)
127        mAdapter.swapCursor(data);
128    }
129
130    // Called when a previously created loader is reset, making the data unavailable
131    public void onLoaderReset(Loader&lt;Cursor> loader) {
132        // This is called when the last Cursor provided to onLoadFinished()
133        // above is about to be closed.  We need to make sure we are no
134        // longer using it.
135        mAdapter.swapCursor(null);
136    }
137
138    &#64;Override 
139    public void onListItemClick(ListView l, View v, int position, long id) {
140        // Do something when a list item is clicked
141    }
142}
143</pre>
144
145<p class="note"><strong>Note:</strong> Because this sample performs a query on the <a
146href="{@docRoot}guide/topics/providers/contacts-provider.html">Contacts
147Provider</a>, if you want to
148try this code, your app must request the {@link android.Manifest.permission#READ_CONTACTS}
149permission in the manifest file:<br/>
150<code>&lt;uses-permission android:name="android.permission.READ_CONTACTS" /></p>
151
152