The Android SDK offers several list controls. Figure 4–6 shows a ListView control that
we’ll discuss in this section.
Figure 4–6. Using the ListView control
The ListView control displays a list of items vertically. You generally use a ListView by
writing a new activity that extends android.app.ListActivity. ListActivity contains a
ListView, and you set the data for the ListView by calling the setListAdapter()
method. For this exercise, we will fill the entire screen with the ListView so we don’t
even need to specify a ListView in our main layout XML file. But we do need to provide
a layout for each row. Listing 4–17 demonstrates the layout file for our row, plus the
Java code for our ListActivity.
Listing 4–17. Adding Items to a ListView <?xml version="1.0" encoding="utf-8"?>
<!-- This file is at /res/layout/list_item.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <CheckBox xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/row_chbox" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<TextView android:id="@+id/row_tv" android:layout_width="wrap_content" android:layout_height="wrap_content"
/>
public class ListDemoActivity extends ListActivity {
private SimpleCursorAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
startManagingCursor(c);
String[] cols = new String[]{People.NAME}; int[] names = new int[]{R.id.row_tv};
adapter = new SimpleCursorAdapter(this,R.layout.list_item,c,cols,names); this.setListAdapter(adapter);
} }
Listing 4–17 creates a ListView control populated with the list of contacts on the device.
To the left of each contact is a check-box control. As we stated earlier, the usage
pattern is to extend ListActivity and then set the list’s adapter by calling
setListAdapter() on the activity. In our example, we query the device for the list of contacts and then create a projection to select only the names of the contacts—a projection defines the columns that we are interested in. We then map a name to a TextView control. Next, we create a cursor adapter and set the list’s adapter. The adapter class has the smarts to take the rows in the data source and pull out the name of each contact to populate the user interface.
There’s one more thing we need to do to make this work. Because this demonstration is accessing the phone’s contacts database, we need to ask permission to do so. This security topic will be covered in more detail in Chapter 7 so, for now, we’ll just walk you
through getting our ListView to show up. Double-click the AndroidManifest.xml file for
this project, then click the Permissions tab. Click the Add… button, choose Uses Permission, and click OK. Scroll down the Name list until you get to
android.permission.READ_CONTACTS. Your Eclipse window should look like Figure 4–7.
Then save the AndroidManifest.xml file. Now you can run this application in the
emulator. You might need to add some contacts using the Contacts application before any names will show up in this example application.
Figure 4–7. Modifying AndroidManifest.xml so our application will run
You’ll notice that the onCreate() method does not set the content view of the activity.
Instead, because the base class ListActivity contains a ListView already, it just needs
to provide the data for the ListView. If you want additional controls in your layout, you
can provide a layout XML file, put in a ListView, and add other desired controls.
For example, you could add a button below the ListView in the UI to submit an action
Figure 4–8. An additional button that lets the user submit the selected item(s)
The layout XML file for this example is broken up into two files. The first contains the
user interface definition of the activity—the ListView and the button (see Figure 4–8 and
Listing 4–18).
Listing 4–18. Overriding the ListView Referenced by ListActivity <?xml version="1.0" encoding="utf-8"?>
<!-- This file is at /res/layout/list.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:stackFromBottom="true" android:transcriptMode="normal"/> <Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Submit Selection" /> </LinearLayout>
The second file contains the definition of the items in the list, which is the same as the definition in Listing 4–17. The activity implementation would then look like Listing 4–19. Listing 4–19. Setting the Content View of the ListActivity
public class ListDemoActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.list);
Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
startManagingCursor(c);
String[] cols = new String[]{People.NAME}; int[] names = new int[]{R.id.row_tv};
adapter = new SimpleCursorAdapter(this,R.layout.list_item,c,cols,names); this.setListAdapter(adapter);
} }
Listing 4–19 shows that the activity calls setContentView() to set the user interface for the activity. It also sets the layout file for the items in the list when it creates the adapter (we’ll talk more about adapters in the “Understanding Adapters” section toward the end of this chapter).