636 lines
24 KiB
Plaintext
636 lines
24 KiB
Plaintext
page.title=Displaying the Quick Contact Badge
|
|
|
|
trainingnavtop=true
|
|
@jd:body
|
|
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<!-- table of contents -->
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li>
|
|
<a href="#AddView">Add a QuickContactBadge View</a>
|
|
</li>
|
|
<li>
|
|
<a href="#SetURIThumbnail">Set the Contact URI and Thumbnail</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ListView">
|
|
Add a QuickContactBadge to a ListView
|
|
</a>
|
|
</li>
|
|
</ol>
|
|
|
|
<!-- other docs (NOT javadocs) -->
|
|
<h2>You should also read</h2>
|
|
<ul>
|
|
<li>
|
|
<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
|
|
Content Provider Basics
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}guide/topics/providers/contacts-provider.html">
|
|
Contacts Provider
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<h2>Try it out</h2>
|
|
|
|
<div class="download-box">
|
|
<a href="http://developer.android.com/shareables/training/ContactsList.zip" class="button">
|
|
Download the sample
|
|
</a>
|
|
<p class="filename">ContactsList.zip</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<p>
|
|
This lesson shows you how to add a {@link android.widget.QuickContactBadge} to your UI
|
|
and how to bind data to it. A {@link android.widget.QuickContactBadge} is a widget that
|
|
initially appears as a thumbnail image. Although you can use any {@link android.graphics.Bitmap}
|
|
for the thumbnail image, you usually use a {@link android.graphics.Bitmap} decoded from the
|
|
contact's photo thumbnail image.
|
|
</p>
|
|
<p>
|
|
The small image acts as a control; when users click on the image, the
|
|
{@link android.widget.QuickContactBadge} expands into a dialog containing the following:
|
|
</p>
|
|
<dl>
|
|
<dt>A large image</dt>
|
|
<dd>
|
|
The large image associated with the contact, or no image is available, a placeholder
|
|
graphic.
|
|
</dd>
|
|
<dt>
|
|
App icons
|
|
</dt>
|
|
<dd>
|
|
An app icon for each piece of detail data that can be handled by a built-in app. For
|
|
example, if the contact's details include one or more email addresses, an email icon
|
|
appears. When users click the icon, all of the contact's email addresses appear. When users
|
|
click one of the addresses, the email app displays a screen for composing a message to the
|
|
selected email address.
|
|
</dd>
|
|
</dl>
|
|
<p>
|
|
The {@link android.widget.QuickContactBadge} view provides instant access to a contact's
|
|
details, as well as a fast way of communicating with the contact. Users don't have to look up
|
|
a contact, find and copy information, and then paste it into the appropriate app. Instead, they
|
|
can click on the {@link android.widget.QuickContactBadge}, choose the communication method they
|
|
want to use, and send the information for that method directly to the appropriate app.
|
|
</p>
|
|
<h2 id="AddView">Add a QuickContactBadge View</h2>
|
|
<p>
|
|
To add a {@link android.widget.QuickContactBadge}, insert a
|
|
<code><QuickContactBadge></code> element in your layout. For example:
|
|
</p>
|
|
<pre>
|
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
android:layout_width="match_parent"
|
|
android:layout_height="match_parent">
|
|
...
|
|
<QuickContactBadge
|
|
android:id=@+id/quickbadge
|
|
android:layout_height="wrap_content"
|
|
android:layout_width="wrap_content"
|
|
android:scaleType="centerCrop"/>
|
|
...
|
|
</RelativeLayout>
|
|
</pre>
|
|
<h2 id="">Retrieve provider data</h2>
|
|
<p>
|
|
To display a contact in the {@link android.widget.QuickContactBadge}, you need a content URI
|
|
for the contact and a {@link android.graphics.Bitmap} for the small image. You generate
|
|
both the content URI and the {@link android.graphics.Bitmap} from columns retrieved from the
|
|
Contacts Provider. Specify these columns as part of the projection you use to load data into
|
|
your {@link android.database.Cursor}.
|
|
</p>
|
|
<p>
|
|
For Android 3.0 (API level 11) and later, include the following columns in your projection:</p>
|
|
<ul>
|
|
<li>{@link android.provider.ContactsContract.Contacts#_ID Contacts._ID}</li>
|
|
<li>{@link android.provider.ContactsContract.Contacts#LOOKUP_KEY Contacts.LOOKUP_KEY}</li>
|
|
<li>
|
|
{@link android.provider.ContactsContract.Contacts#PHOTO_THUMBNAIL_URI
|
|
Contacts.PHOTO_THUMBNAIL_URI}
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
For Android 2.3.3 (API level 10) and earlier, use the following columns:
|
|
</p>
|
|
<ul>
|
|
<li>{@link android.provider.ContactsContract.Contacts#_ID Contacts._ID}</li>
|
|
<li>{@link android.provider.ContactsContract.Contacts#LOOKUP_KEY Contacts.LOOKUP_KEY}</li>
|
|
</ul>
|
|
<p>
|
|
The remainder of this lesson assumes that you've already loaded a
|
|
{@link android.database.Cursor} that contains these columns as well as others you may have
|
|
chosen. To learn how to retrieve this columns in a {@link android.database.Cursor}, read the
|
|
lesson <a href="retrieve-names.html">Retrieving a List of Contacts</a>.
|
|
</p>
|
|
<h2 id="SetURIThumbnail">Set the Contact URI and Thumbnail</h2>
|
|
<p>
|
|
Once you have the necessary columns, you can bind data to the
|
|
{@link android.widget.QuickContactBadge}.
|
|
</p>
|
|
<h3>Set the Contact URI</h3>
|
|
<p>
|
|
To set the content URI for the contact, call
|
|
{@link android.provider.ContactsContract.Contacts#getLookupUri getLookupUri(id,lookupKey)} to
|
|
get a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, then
|
|
call {@link android.widget.QuickContactBadge#assignContactUri assignContactUri()} to set the
|
|
contact. For example:
|
|
</p>
|
|
<pre>
|
|
// The Cursor that contains contact rows
|
|
Cursor mCursor;
|
|
// The index of the _ID column in the Cursor
|
|
int mIdColumn;
|
|
// The index of the LOOKUP_KEY column in the Cursor
|
|
int mLookupKeyColumn;
|
|
// A content URI for the desired contact
|
|
Uri mContactUri;
|
|
// A handle to the QuickContactBadge view
|
|
QuickContactBadge mBadge;
|
|
...
|
|
mBadge = (QuickContactBadge) findViewById(R.id.quickbadge);
|
|
/*
|
|
* Insert code here to move to the desired cursor row
|
|
*/
|
|
// Gets the _ID column index
|
|
mIdColumn = mCursor.getColumnIndex(Contacts._ID);
|
|
// Gets the LOOKUP_KEY index
|
|
mLookupKeyColumn = mCursor.getColumnIndex(Contacts.LOOKUP_KEY);
|
|
// Gets a content URI for the contact
|
|
mContactUri =
|
|
Contacts.getLookupUri(
|
|
mCursor.getLong(mIdColumn),
|
|
mCursor.getString(mLookupKeyColumn)
|
|
);
|
|
mBadge.assignContactUri(mContactUri);
|
|
</pre>
|
|
<p>
|
|
When users click the {@link android.widget.QuickContactBadge} icon, the contact's
|
|
details automatically appear in the dialog.
|
|
</p>
|
|
<h3>Set the photo thumbnail</h3>
|
|
<p>
|
|
Setting the contact URI for the {@link android.widget.QuickContactBadge} does not automatically
|
|
load the contact's thumbnail photo. To load the photo, get a URI for the photo from the
|
|
contact's {@link android.database.Cursor} row, use it to open the file containing the compressed
|
|
thumbnail photo, and read the file into a {@link android.graphics.Bitmap}.
|
|
</p>
|
|
<p class="note">
|
|
<strong>Note:</strong> The
|
|
{@link android.provider.ContactsContract.Contacts#PHOTO_THUMBNAIL_URI} column isn't available
|
|
in platform versions prior to 3.0. For those versions, you must retrieve the URI
|
|
from the {@link android.provider.ContactsContract.Contacts.Photo Contacts.Photo} subtable.
|
|
</p>
|
|
<p>
|
|
First, set up variables for accessing the {@link android.database.Cursor} containing the
|
|
{@link android.provider.ContactsContract.Contacts#_ID Contacts._ID} and
|
|
{@link android.provider.ContactsContract.Contacts#LOOKUP_KEY Contacts.LOOKUP_KEY} columns, as
|
|
described previously:
|
|
</p>
|
|
<pre>
|
|
// The column in which to find the thumbnail ID
|
|
int mThumbnailColumn;
|
|
/*
|
|
* The thumbnail URI, expressed as a String.
|
|
* Contacts Provider stores URIs as String values.
|
|
*/
|
|
String mThumbnailUri;
|
|
...
|
|
/*
|
|
* Gets the photo thumbnail column index if
|
|
* platform version >= Honeycomb
|
|
*/
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
|
mThumbnailColumn =
|
|
mCursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI);
|
|
// Otherwise, sets the thumbnail column to the _ID column
|
|
} else {
|
|
mThumbnailColumn = mIdColumn;
|
|
}
|
|
/*
|
|
* Assuming the current Cursor position is the contact you want,
|
|
* gets the thumbnail ID
|
|
*/
|
|
mThumbnailUri = mCursor.getString(mThumbnailColumn);
|
|
...
|
|
</pre>
|
|
<p>
|
|
Define a method that takes photo-related data for the contact and dimensions for the
|
|
destination view, and returns the properly-sized thumbnail in a
|
|
{@link android.graphics.Bitmap}. Start by constructing a URI that points to the
|
|
thumbnail:
|
|
<p>
|
|
<pre>
|
|
/**
|
|
* Load a contact photo thumbnail and return it as a Bitmap,
|
|
* resizing the image to the provided image dimensions as needed.
|
|
* @param photoData photo ID Prior to Honeycomb, the contact's _ID value.
|
|
* For Honeycomb and later, the value of PHOTO_THUMBNAIL_URI.
|
|
* @return A thumbnail Bitmap, sized to the provided width and height.
|
|
* Returns null if the thumbnail is not found.
|
|
*/
|
|
private Bitmap loadContactPhotoThumbnail(String photoData) {
|
|
// Creates an asset file descriptor for the thumbnail file.
|
|
AssetFileDescriptor afd = null;
|
|
// try-catch block for file not found
|
|
try {
|
|
// Creates a holder for the URI.
|
|
Uri thumbUri;
|
|
// If Android 3.0 or later
|
|
if (Build.VERSION.SDK_INT
|
|
>=
|
|
Build.VERSION_CODES.HONEYCOMB) {
|
|
// Sets the URI from the incoming PHOTO_THUMBNAIL_URI
|
|
thumbUri = Uri.parse(photoData);
|
|
} else {
|
|
// Prior to Android 3.0, constructs a photo Uri using _ID
|
|
/*
|
|
* Creates a contact URI from the Contacts content URI
|
|
* incoming photoData (_ID)
|
|
*/
|
|
final Uri contactUri = Uri.withAppendedPath(
|
|
Contacts.CONTENT_URI, photoData);
|
|
/*
|
|
* Creates a photo URI by appending the content URI of
|
|
* Contacts.Photo.
|
|
*/
|
|
thumbUri =
|
|
Uri.withAppendedPath(
|
|
contactUri, Photo.CONTENT_DIRECTORY);
|
|
}
|
|
|
|
/*
|
|
* Retrieves an AssetFileDescriptor object for the thumbnail
|
|
* URI
|
|
* using ContentResolver.openAssetFileDescriptor
|
|
*/
|
|
afd = getActivity().getContentResolver().
|
|
openAssetFileDescriptor(thumbUri, "r");
|
|
/*
|
|
* Gets a file descriptor from the asset file descriptor.
|
|
* This object can be used across processes.
|
|
*/
|
|
FileDescriptor fileDescriptor = afd.getFileDescriptor();
|
|
// Decode the photo file and return the result as a Bitmap
|
|
// If the file descriptor is valid
|
|
if (fileDescriptor != null) {
|
|
// Decodes the bitmap
|
|
return BitmapFactory.decodeFileDescriptor(
|
|
fileDescriptor, null, null);
|
|
}
|
|
// If the file isn't found
|
|
} catch (FileNotFoundException e) {
|
|
/*
|
|
* Handle file not found errors
|
|
*/
|
|
}
|
|
// In all cases, close the asset file descriptor
|
|
} finally {
|
|
if (afd != null) {
|
|
try {
|
|
afd.close();
|
|
} catch (IOException e) {}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
</pre>
|
|
<p>
|
|
Call the <code>loadContactPhotoThumbnail()</code> method in your code to get the
|
|
thumbnail {@link android.graphics.Bitmap}, and use the result to set the photo thumbnail in
|
|
your {@link android.widget.QuickContactBadge}:
|
|
</p>
|
|
<pre>
|
|
...
|
|
/*
|
|
* Decodes the thumbnail file to a Bitmap.
|
|
*/
|
|
Bitmap mThumbnail =
|
|
loadContactPhotoThumbnail(mThumbnailUri);
|
|
/*
|
|
* Sets the image in the QuickContactBadge
|
|
* QuickContactBadge inherits from ImageView, so
|
|
*/
|
|
mBadge.setImageBitmap(mThumbnail);
|
|
</pre>
|
|
<h2 id="ListView">Add a QuickContactBadge to a ListView</h2>
|
|
<p>
|
|
A {@link android.widget.QuickContactBadge} is a useful addition to a
|
|
{@link android.widget.ListView} that displays a list of contacts. Use the
|
|
{@link android.widget.QuickContactBadge} to display a thumbnail photo for each contact; when
|
|
users click the thumbnail, the {@link android.widget.QuickContactBadge} dialog appears.
|
|
</p>
|
|
<h3>Add the QuickContactBadge element</h3>
|
|
<p>
|
|
To start, add a {@link android.widget.QuickContactBadge} view element to your item layout
|
|
For example, if you want to display a {@link android.widget.QuickContactBadge} and a name for
|
|
each contact you retrieve, put the following XML into a layout file:
|
|
</p>
|
|
<pre>
|
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
android:layout_width="match_parent"
|
|
android:layout_height="wrap_content">
|
|
<QuickContactBadge
|
|
android:id="@+id/quickcontact"
|
|
android:layout_height="wrap_content"
|
|
android:layout_width="wrap_content"
|
|
android:scaleType="centerCrop"/>
|
|
<TextView android:id="@+id/displayname"
|
|
android:layout_width="match_parent"
|
|
android:layout_height="wrap_content"
|
|
android:layout_toRightOf="@+id/quickcontact"
|
|
android:gravity="center_vertical"
|
|
android:layout_alignParentRight="true"
|
|
android:layout_alignParentTop="true"/>
|
|
</RelativeLayout>
|
|
</pre>
|
|
<p>
|
|
In the following sections, this file is referred to as <code>contact_item_layout.xml</code>.
|
|
</p>
|
|
<h3>Set up a custom CursorAdapter</h3>
|
|
<p>
|
|
To bind a {@link android.support.v4.widget.CursorAdapter} to a {@link android.widget.ListView}
|
|
containing a {@link android.widget.QuickContactBadge}, define a custom adapter that
|
|
extends {@link android.support.v4.widget.CursorAdapter}. This approach allows you to process the
|
|
data in the {@link android.database.Cursor} before you bind it to the
|
|
{@link android.widget.QuickContactBadge}. This approach also allows you to bind multiple
|
|
{@link android.database.Cursor} columns to the {@link android.widget.QuickContactBadge}. Neither
|
|
of these operations is possible in a regular {@link android.support.v4.widget.CursorAdapter}.
|
|
</p>
|
|
<p>
|
|
The subclass of {@link android.support.v4.widget.CursorAdapter} that you define must
|
|
override the following methods:
|
|
</p>
|
|
<dl>
|
|
<dt>{@link android.support.v4.widget.CursorAdapter#newView CursorAdapter.newView()}</dt>
|
|
<dd>
|
|
Inflates a new {@link android.view.View} object to hold the item layout. In the override
|
|
of this method, store handles to the child {@link android.view.View} objects of the layout,
|
|
including the child {@link android.widget.QuickContactBadge}. By taking this approach, you
|
|
avoid having to get handles to the child {@link android.view.View} objects each time you
|
|
inflate a new layout.
|
|
<p>
|
|
You must override this method so you can get handles to the individual child
|
|
{@link android.view.View} objects. This technique allows you to control their binding in
|
|
{@link android.support.v4.widget.CursorAdapter#bindView CursorAdapter.bindView()}.
|
|
</p>
|
|
</dd>
|
|
<dt>{@link android.support.v4.widget.CursorAdapter#bindView CursorAdapter.bindView()}</dt>
|
|
<dd>
|
|
Moves data from the current {@link android.database.Cursor} row to the child
|
|
{@link android.view.View} objects of the item layout. You must override this method so
|
|
you can bind both the contact's URI and thumbnail to the
|
|
{@link android.widget.QuickContactBadge}. The default implementation only allows a 1-to-1
|
|
mapping between a column and a {@link android.view.View}
|
|
</dd>
|
|
</dl>
|
|
<p>
|
|
The following code snippet contains an example of a custom subclass of
|
|
{@link android.support.v4.widget.CursorAdapter}:
|
|
</p>
|
|
<h3>Define the custom list adapter</h3>
|
|
<p>
|
|
Define the subclass of {@link android.support.v4.widget.CursorAdapter} including its
|
|
constructor, and override
|
|
{@link android.support.v4.widget.CursorAdapter#newView newView()} and
|
|
{@link android.support.v4.widget.CursorAdapter#bindView bindView()}:
|
|
</p>
|
|
<pre>
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
private class ContactsAdapter extends CursorAdapter {
|
|
private LayoutInflater mInflater;
|
|
...
|
|
public ContactsAdapter(Context context) {
|
|
super(context, null, 0);
|
|
|
|
/*
|
|
* Gets an inflater that can instantiate
|
|
* the ListView layout from the file.
|
|
*/
|
|
mInflater = LayoutInflater.from(context);
|
|
...
|
|
}
|
|
...
|
|
/**
|
|
* Defines a class that hold resource IDs of each item layout
|
|
* row to prevent having to look them up each time data is
|
|
* bound to a row.
|
|
*/
|
|
private class ViewHolder {
|
|
TextView displayname;
|
|
QuickContactBadge quickcontact;
|
|
}
|
|
..
|
|
@Override
|
|
public View newView(
|
|
Context context,
|
|
Cursor cursor,
|
|
ViewGroup viewGroup) {
|
|
/* Inflates the item layout. Stores resource IDs in a
|
|
* in a ViewHolder class to prevent having to look
|
|
* them up each time bindView() is called.
|
|
*/
|
|
final View itemView =
|
|
mInflater.inflate(
|
|
R.layout.contact_list_layout,
|
|
viewGroup,
|
|
false
|
|
);
|
|
final ViewHolder holder = new ViewHolder();
|
|
holder.displayname =
|
|
(TextView) view.findViewById(R.id.displayname);
|
|
holder.quickcontact =
|
|
(QuickContactBadge)
|
|
view.findViewById(R.id.quickcontact);
|
|
view.setTag(holder);
|
|
return view;
|
|
}
|
|
...
|
|
@Override
|
|
public void bindView(
|
|
View view,
|
|
Context context,
|
|
Cursor cursor) {
|
|
final ViewHolder holder = (ViewHolder) view.getTag();
|
|
final String photoData =
|
|
cursor.getString(mPhotoDataIndex);
|
|
final String displayName =
|
|
cursor.getString(mDisplayNameIndex);
|
|
...
|
|
// Sets the display name in the layout
|
|
holder.displayname = cursor.getString(mDisplayNameIndex);
|
|
...
|
|
/*
|
|
* Generates a contact URI for the QuickContactBadge.
|
|
*/
|
|
final Uri contactUri = Contacts.getLookupUri(
|
|
cursor.getLong(mIdIndex),
|
|
cursor.getString(mLookupKeyIndex));
|
|
holder.quickcontact.assignContactUri(contactUri);
|
|
String photoData = cursor.getString(mPhotoDataIndex);
|
|
/*
|
|
* Decodes the thumbnail file to a Bitmap.
|
|
* The method loadContactPhotoThumbnail() is defined
|
|
* in the section "Set the Contact URI and Thumbnail"
|
|
*/
|
|
Bitmap thumbnailBitmap =
|
|
loadContactPhotoThumbnail(photoData);
|
|
/*
|
|
* Sets the image in the QuickContactBadge
|
|
* QuickContactBadge inherits from ImageView
|
|
*/
|
|
holder.quickcontact.setImageBitmap(thumbnailBitmap);
|
|
}
|
|
</pre>
|
|
|
|
<h3>Set up variables</h3>
|
|
<p>
|
|
In your code, set up variables, including a {@link android.database.Cursor} projection that
|
|
includes the necessary columns.
|
|
</p>
|
|
<p class="note">
|
|
<strong>Note:</strong> The following code snippets use the method
|
|
<code>loadContactPhotoThumbnail()</code>, which is defined in the section
|
|
<a href="#SetURIThumbnail">Set the Contact URI and Thumbnail</a>
|
|
</p>
|
|
<p>
|
|
For example:
|
|
</p>
|
|
<pre>
|
|
public class ContactsFragment extends Fragment implements
|
|
LoaderManager.LoaderCallbacks<Cursor> {
|
|
...
|
|
// Defines a ListView
|
|
private ListView mListView;
|
|
// Defines a ContactsAdapter
|
|
private ContactsAdapter mAdapter;
|
|
...
|
|
// Defines a Cursor to contain the retrieved data
|
|
private Cursor mCursor;
|
|
/*
|
|
* Defines a projection based on platform version. This ensures
|
|
* that you retrieve the correct columns.
|
|
*/
|
|
private static final String[] PROJECTION =
|
|
{
|
|
Contacts._ID,
|
|
Contacts.LOOKUP_KEY,
|
|
(Build.VERSION.SDK_INT >=
|
|
Build.VERSION_CODES.HONEYCOMB) ?
|
|
Contacts.DISPLAY_NAME_PRIMARY :
|
|
Contacts.DISPLAY_NAME
|
|
(Build.VERSION.SDK_INT >=
|
|
Build.VERSION_CODES.HONEYCOMB) ?
|
|
Contacts.PHOTO_THUMBNAIL_ID :
|
|
/*
|
|
* Although it's not necessary to include the
|
|
* column twice, this keeps the number of
|
|
* columns the same regardless of version
|
|
*/
|
|
Contacts_ID
|
|
...
|
|
};
|
|
/*
|
|
* As a shortcut, defines constants for the
|
|
* column indexes in the Cursor. The index is
|
|
* 0-based and always matches the column order
|
|
* in the projection.
|
|
*/
|
|
// Column index of the _ID column
|
|
private int mIdIndex = 0;
|
|
// Column index of the LOOKUP_KEY column
|
|
private int mLookupKeyIndex = 1;
|
|
// Column index of the display name column
|
|
private int mDisplayNameIndex = 3;
|
|
/*
|
|
* Column index of the photo data column.
|
|
* It's PHOTO_THUMBNAIL_URI for Honeycomb and later,
|
|
* and _ID for previous versions.
|
|
*/
|
|
private int mPhotoDataIndex =
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
|
|
3 :
|
|
0;
|
|
...
|
|
</pre>
|
|
<h3>Set up the ListView</h3>
|
|
<p>
|
|
In {@link android.support.v4.app.Fragment#onCreate Fragment.onCreate()}, instantiate the custom
|
|
cursor adapter and get a handle to the {@link android.widget.ListView}:
|
|
</p>
|
|
<pre>
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
...
|
|
/*
|
|
* Instantiates the subclass of
|
|
* CursorAdapter
|
|
*/
|
|
ContactsAdapter mContactsAdapter =
|
|
new ContactsAdapter(getActivity());
|
|
/*
|
|
* Gets a handle to the ListView in the file
|
|
* contact_list_layout.xml
|
|
*/
|
|
mListView = (ListView) findViewById(R.layout.contact_list_layout);
|
|
...
|
|
}
|
|
...
|
|
</pre>
|
|
<p>
|
|
In {@link android.support.v4.app.Fragment#onActivityCreated onActivityCreated()}, bind the
|
|
<code>ContactsAdapter</code> to the {@link android.widget.ListView}:
|
|
</p>
|
|
<pre>
|
|
@Override
|
|
public void onActivityCreated(Bundle savedInstanceState) {
|
|
...
|
|
// Sets up the adapter for the ListView
|
|
mListView.setAdapter(mAdapter);
|
|
...
|
|
}
|
|
...
|
|
</pre>
|
|
<p>
|
|
When you get back a {@link android.database.Cursor} containing the contacts data, usually in
|
|
{@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
|
|
call {@link android.support.v4.widget.CursorAdapter#swapCursor swapCursor()} to move the
|
|
{@link android.database.Cursor} data to the {@link android.widget.ListView}. This displays the
|
|
{@link android.widget.QuickContactBadge} for each entry in the list of contacts:
|
|
</p>
|
|
<pre>
|
|
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
|
// When the loader has completed, swap the cursor into the adapter.
|
|
mContactsAdapter.swapCursor(cursor);
|
|
}
|
|
</pre>
|
|
<p>
|
|
When you bind a {@link android.database.Cursor} to a
|
|
{@link android.widget.ListView} with a {@link android.support.v4.widget.CursorAdapter}
|
|
(or subclass), and you use a {@link android.support.v4.content.CursorLoader} to load the
|
|
{@link android.database.Cursor}, always clear references to the {@link android.database.Cursor}
|
|
in your implementation of
|
|
{@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}.
|
|
For example:
|
|
</p>
|
|
<pre>
|
|
@Override
|
|
public void onLoaderReset(Loader<Cursor> loader) {
|
|
// Removes remaining reference to the previous Cursor
|
|
mContactsAdapter.swapCursor(null);
|
|
}
|
|
</pre>
|