the various properties (namely, the unique identifier, the display name or title, and the value of the constant).
Adapting to the Circumstances
Now that we have a Cursor
via managedQuery()
, we have access to the query results and can do whatever we want with them. You might, for example, manually extract data from the Cursor
to populate widgets or other objects.
However, if the goal of the query was to return a list from which the user should choose an item, you probably should consider using SimpleCursorAdapter
. This class bridges between the Cursor
and a selection widget, such as a ListView
or Spinner
. Pour the Cursor
into a SimpleCursorAdapter
, hand the adapter off to the widget, and you’re set — your widget will show the available options.
For example, here is the onCreate()
method from ConstantsBrowser
, which gives the user a list of physical constants:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
constantsCursor = managedQuery (Provider.Constants.CONTENT_URI,
PROJECTION, null, null, null);
ListAdapter adapter = new SimpleCursorAdapter (this,
R.layout.row, constantsCursor,
new String[] {Provider.Constants.TITLE, Provider.Constants.VALUE},
new int[] {R.id.title, R.id.value});
setListAdapter(adapter);
registerForContextMenu(getListView());
}
After executing the managedQuery()
and getting the Cursor
, ConstantsBrowser
creates a SimpleCursorAdapter
with the following parameters:
• The activity (or other Context
) creating the adapter; in this case, the ConstantsBrowser
itself
• The identifier for a layout to be used for rendering the list entries (R.layout.row
)
• The cursor (constantsCursor
)
• The properties to pull out of the cursor and use for configuring the list entry View instances (TITLE
and VALUE
)
• The corresponding identifiers of TextView
widgets in the list entry layout that those properties should go into (R.id.title
and R.id.value
)
After that, we put the adapter into the ListView
, and we get the results shown in Figure 27-1.

Figure 27-1.
If you need more control over the views than you can reasonably achieve with the stock view construction logic, subclass SimpleCursorAdapter
and override getView()
to create your own widgets to go into the list, as demonstrated in Chapter 9.
Doing It By Hand
Of course, you can always do it the “hard way” — pulling data out of the Cursor
by hand. The Cursor
interface is similar in concept to other database access APIs offering cursors as objects, though, as always, the devil is in the details.
Position
Cursor instances have a built-in notion of position, akin to the Java Iterator interface. To get to the various rows, you can use:
• moveToFirst()
to move to the first row in the result set or moveToLast()
to move to the last row in the result set
• moveToNext()
to move to the next row and determine if there is yet another row to process (moveToNext()
returns true if it points to another row after moving, false otherwise)
• moveToPrevious()
to move to the previous row, as the opposite to moveToNext ()
• moveToPosition()
to move to a specific index, or move()
to move to a relative position plus or minus from your current position
• getPosition()
to return your current index
• a whole host of condition methods, including isFirst()
, isLast()
, isBeforeFirst()
, and isAfterLast()
Getting Properties
Once you have the Cursor positioned at a row of interest, you have a variety of methods to retrieve properties from that row, with different methods supporting different types (getString()
, getInt()
, getFloat()
, etc.). Each method takes the zero-based index of the property you want to retrieve.
If you want to see if a given property has a value, you can use isNull()
to test it for null
-ness.
Give and Take