בדף הזה מוסבר איך להוסיף QuickContactBadge
לממשק המשתמש ואיך לקשר אליו נתונים. QuickContactBadge
הוא ווידג'ט שמופיע בהתחלה כתמונה ממוזערת. למרות שאפשר להשתמש בכל Bitmap
לתמונה הממוזערת, בדרך כלל משתמשים ב-Bitmap
מפוענח מהתמונה הממוזערת של איש הקשר.
התמונה הקטנה משמשת כפקד. כשמשתמשים מקישים על התמונה, QuickContactBadge
מתרחב בתיבת דו-שיח שמכילה את הדברים הבאים:
- תמונה גדולה
- התמונה הגדולה שמשויכת לאיש הקשר, או אם אין תמונה זמינה, גרפיקה של placeholder.
- סמלים של אפליקציות
- סמל האפליקציה לכל פרט של נתונים מפורטים שאפליקציה מובנית יכולה לטפל בהם. לדוגמה, אם הפרטים של איש הקשר כוללים כתובת אימייל אחת או יותר, יופיע סמל אימייל. כשמשתמשים מקישים על הסמל, מופיעות כל כתובות האימייל של איש הקשר. כשמשתמשים מקישים על אחת מהכתובות, באפליקציית האימייל מוצג מסך לניסוח הודעה לכתובת האימייל שנבחרה.
התצוגה QuickContactBadge
מספקת גישה מיידית לפרטים של איש הקשר ודרך מהירה לתקשר עם איש הקשר. המשתמשים לא צריכים לחפש איש קשר, למצוא מידע ולהעתיק אותו, ואז להדביק אותו באפליקציה המתאימה. במקום זאת, הם יכולים להקיש על QuickContactBadge
, לבחור את שיטת התקשורת שבה הם רוצים להשתמש ולשלוח את המידע לגבי השיטה הזו ישירות לאפליקציה המתאימה.
הוספת תצוגה של QuickContactBadge
כדי להוסיף QuickContactBadge
, מוסיפים אלמנט <QuickContactBadge>
לפריסה, כפי שמוצג בדוגמה הבאה:
<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>
אחזור נתוני ספק
כדי להציג איש קשר ב-QuickContactBadge
, נדרש URI של תוכן לאיש הקשר ו-Bitmap
לתמונה הקטנה. יוצרים את URI התוכן ואת Bitmap
מהעמודות שאוחזרו מספק אנשי הקשר. מציינים את העמודות האלה כחלק מההיטל שבו משתמשים כדי לטעון נתונים אל Cursor
.
ל-Android 3.0 (רמת API 11) ואילך, יש לכלול את העמודות הבאות בתחזית:
ל-Android 2.3.3 (רמת API 10) ומטה, משתמשים בעמודות הבאות:
בדוגמאות בדף הזה מניחים שטענתם Cursor
שמכיל את העמודות האלה ואת כל העמודות האחרות שבחרתם. במאמר אחזור רשימת אנשי קשר מוסבר איך מאחזרים עמודות ב-Cursor
.
הגדרת ה-URI של איש הקשר והתמונה הממוזערת שלו
אחרי שיוצרים את העמודות הנדרשות, אפשר לקשר נתונים ל-QuickContactBadge
.
הגדרת ה-URI של איש הקשר
כדי להגדיר את URI התוכן של איש הקשר, צריך להפעיל את השיטה getLookupUri(id,lookupKey)
כדי לקבל CONTENT_LOOKUP_URI
, ואז להפעיל את השיטה assignContactUri()
כדי להגדיר את איש הקשר. הדוגמה הבאה ממחישה זאת:
Kotlin
// The Cursor that contains contact rows var cursor: Cursor? = null // The index of the _ID column in the Cursor var idColumn: Int = 0 // The index of the LOOKUP_KEY column in the Cursor var lookupKeyColumn: Int = 0 // A content URI for the desired contact var contactUri: Uri? = null // A handle to the QuickContactBadge view ... cursor?.let { cursor -> /* * Insert code here to move to the desired cursor row */ // Gets the _ID column index idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID) // Gets the LOOKUP_KEY index lookupKeyColumn = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY) // Gets a content URI for the contact contactUri = ContactsContract.Contacts.getLookupUri( cursor.getLong(idColumn), cursor.getString(lookupKeyColumn) ) binding.badge.assignContactUri(contactUri) }
Java
// The Cursor that contains contact rows Cursor cursor; // The index of the _ID column in the Cursor int idColumn; // The index of the LOOKUP_KEY column in the Cursor int lookupKeyColumn; // A content URI for the desired contact Uri contactUri; ... /* * Insert code here to move to the desired cursor row */ // Gets the _ID column index idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); // Gets the LOOKUP_KEY index lookupKeyColumn = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); // Gets a content URI for the contact contactUri = Contacts.getLookupUri( cursor.getLong(idColumn), cursor.getString(lookupKeyColumn) ); binding.badge.assignContactUri(contactUri);
כשמשתמשים מקישים על הסמל QuickContactBadge
, הפרטים של איש הקשר מופיעים בתיבת הדו-שיח.
הגדרת התמונה הממוזערת
הגדרת כתובת ה-URI של איש הקשר ב-QuickContactBadge
לא טוענת באופן אוטומטי את התמונה הממוזערת של איש הקשר. כדי לטעון את התמונה, מקבלים URI של התמונה מהשורה Cursor
של איש הקשר, משתמשים בו כדי לפתוח את הקובץ שמכיל את התמונה הממוזערת המצומצמת, וקוראים את הקובץ ל-Bitmap
.
הערה: העמודה PHOTO_THUMBNAIL_URI
לא זמינה בגרסאות פלטפורמה שקדמו לגרסה 3.0. לגרסאות האלה, צריך לאחזר את ה-URI מהטבלת המשנה Contacts.Photo
.
קודם צריך להגדיר משתנים כדי לגשת למערך Cursor
שמכיל את העמודות Contacts._ID
ו-Contacts.LOOKUP_KEY
:
Kotlin
// The column in which to find the thumbnail ID var thumbnailColumn: Int = 0 /* * The thumbnail URI, expressed as a String. * Contacts Provider stores URIs as String values. */ var thumbnailUri: String? = null ... cursor?.let { cursor -> /* * Gets the photo thumbnail column index if * platform version >= Honeycomb */ thumbnailColumn = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI) // Otherwise, sets the thumbnail column to the _ID column } else { idColumn } /* * Assuming the current Cursor position is the contact you want, * gets the thumbnail ID */ thumbnailUri = cursor.getString(thumbnailColumn) }
Java
// The column in which to find the thumbnail ID int thumbnailColumn; /* * The thumbnail URI, expressed as a String. * Contacts Provider stores URIs as String values. */ String thumbnailUri; ... /* * Gets the photo thumbnail column index if * platform version >= Honeycomb */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { thumbnailColumn = cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI); // Otherwise, sets the thumbnail column to the _ID column } else { thumbnailColumn = idColumn; } /* * Assuming the current Cursor position is the contact you want, * gets the thumbnail ID */ thumbnailUri = cursor.getString(thumbnailColumn); ...
מגדירים שיטה שמקבלת נתונים שקשורים לתמונה של איש הקשר ואת המימדים של תצוגת היעד, ומחזירה את התמונה הממוזערת בגודל המתאים ב-Bitmap
. מתחילים ביצירת URI שמפנה לתמונה הממוזערת:
Kotlin
/** * 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 fun loadContactPhotoThumbnail(photoData: String): Bitmap? { // Creates an asset file descriptor for the thumbnail file var afd: AssetFileDescriptor? = null // try-catch block for file not found try { // Creates a holder for the URI val thumbUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // If Android 3.0 or later, // sets the URI from the incoming PHOTO_THUMBNAIL_URI 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) */ val contactUri: Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, photoData) /* * Creates a photo URI by appending the content URI of * Contacts.Photo */ Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY) } /* * Retrieves an AssetFileDescriptor object for the thumbnail URI * using ContentResolver.openAssetFileDescriptor */ afd = activity?.contentResolver?.openAssetFileDescriptor(thumbUri, "r") /* * Gets a file descriptor from the asset file descriptor. * This object can be used across processes. */ return afd?.fileDescriptor?.let {fileDescriptor -> // Decodes the photo file and returns the result as a Bitmap // if the file descriptor is valid BitmapFactory.decodeFileDescriptor(fileDescriptor, null, null) } } catch (e: FileNotFoundException) { /* * Handle file not found errors */ null } finally { // In all cases, close the asset file descriptor try { afd?.close() } catch (e: IOException) { } } }
Java
/** * 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( ContactsContract.Contacts.CONTENT_URI, photoData); /* * Creates a photo URI by appending the content URI of * Contacts.Photo */ thumbUri = Uri.withAppendedPath( contactUri, ContactsContract.Contacts.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(); // Decodes the photo file and returns 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; }
קוראים ל-method loadContactPhotoThumbnail()
בקוד כדי לקבל את התמונה הממוזערת Bitmap
, ומשתמשים בתוצאה כדי להגדיר את התמונה הממוזערת של התמונה
ב-QuickContactBadge
:
Kotlin
... /* * Decodes the thumbnail file to a Bitmap */ mThumbnailUri?.also { thumbnailUri -> loadContactPhotoThumbnail(thumbnailUri).also { thumbnail -> /* * Sets the image in the QuickContactBadge. * QuickContactBadge inherits from ImageView. */ badge.setImageBitmap(thumbnail) } }
Java
... /* * Decodes the thumbnail file to a Bitmap */ Bitmap mThumbnail = loadContactPhotoThumbnail(thumbnailUri); /* * Sets the image in the QuickContactBadge. * QuickContactBadge inherits from ImageView. */ badge.setImageBitmap(mThumbnail);
הוספת QuickContactBadge ל-ListView
QuickContactBadge
הוא תוספת שימושית ל-ListView
שמוצגת בו רשימת אנשי קשר. משתמשים ב-QuickContactBadge
כדי להציג תמונה ממוזערת של כל איש קשר. כשמשתמשים מקישים על התמונה הממוזערת, תיבת הדו-שיח QuickContactBadge
מופיעה.
הוספת הרכיב QuickContactBadge
כדי להתחיל, מוסיפים אלמנט תצוגה מסוג QuickContactBadge
לפריסה של הפריט. לדוגמה, אם רוצים להציג QuickContactBadge
ושם לכל איש קשר שאוחזר, מוסיפים את ה-XML הבא לקובץ פריסה:
<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>
בקטעים הבאים, הקובץ הזה נקרא contact_item_layout.xml
.
הגדרת CursorAdapter בהתאמה אישית
כדי לקשר CursorAdapter
ל-ListView
שמכיל QuickContactBadge
, מגדירים מתאם מותאם אישית שמרחיב את CursorAdapter
. הגישה הזו מאפשרת לעבד את הנתונים ב-Cursor
לפני שמקשרים אותם ל-QuickContactBadge
. הגישה הזו מאפשרת גם לקשר כמה עמודות של Cursor
ל-QuickContactBadge
. אי אפשר לבצע אף אחת מהפעולות האלה ב-CursorAdapter
רגיל.
תת-הסוג של CursorAdapter
שתגדירו חייב לבטל את הגדרת ברירת המחדל של השיטות הבאות:
CursorAdapter.newView()
-
התנפחות של אובייקט
View
חדש כדי לאחסן את פריסת הפריט. בשינוי של השיטה הזו, שומרים את הלחצנים לאובייקטים הצאצאיםView
של הפריסה, כולל הצאצאQuickContactBadge
. הגישה הזו מונעת צורך לקבל כינויים לאובייקטים הצאצאים שלView
בכל פעם שמנפחים פריסה חדשה.צריך לשנות את השיטה הזו כדי לקבל כינויים לאובייקטים הנפרדים של
View
. הטכניקה הזו מאפשרת לכם לשלוט בקישור שלהם ב-CursorAdapter.bindView()
. CursorAdapter.bindView()
-
מעביר נתונים מהשורה הנוכחית
Cursor
לאובייקטים הילדיםView
של פריסת הפריט. צריך לשנות את השיטה הזו כדי שתוכלו לקשר גם את ה-URI וגם את התמונה הממוזערת של איש הקשר ל-QuickContactBadge
. בהטמעה שמוגדרת כברירת מחדל, מותר רק למפות עמודה אחת לערךView
אחד.
קטע הקוד הבא מכיל דוגמה למחלקת משנה בהתאמה אישית של CursorAdapter
:
הגדרת המתאם של הרשימה בהתאמה אישית
מגדירים את תת-המחלקה של CursorAdapter
, כולל ה-constructor שלו, ומבטלים את newView()
ואת bindView()
:
Kotlin
/** * Defines a class that holds resource IDs of each item layout * row to prevent having to look them up each time data is * bound to a row */ private data class ViewHolder( internal var displayname: TextView? = null, internal var quickcontact: QuickContactBadge? = null ) /** * * */ private inner class ContactsAdapter( context: Context, val inflater: LayoutInflater = LayoutInflater.from(context) ) : CursorAdapter(context, null, 0) { ... override fun newView( context: Context, cursor: Cursor, viewGroup: ViewGroup ): View { /* Inflates the item layout. Stores view references * in a ViewHolder class to prevent having to look * them up each time bindView() is called. */ return ContactListLayoutBinding.inflate(inflater, viewGroup, false).also { binding -> view.tag = ViewHolder().apply { displayname = binding.displayname quickcontact = binding.quickcontact } }.root } ... override fun bindView(view: View?, context: Context?, cursor: Cursor?) { (view?.tag as? ViewHolder)?.also { holder -> cursor?.apply { ... // Sets the display name in the layout holder.displayname?.text = getString(displayNameIndex) ... /* * Generates a contact URI for the QuickContactBadge */ ContactsContract.Contacts.getLookupUri( getLong(idIndex), cursor.getString(lookupKeyIndex) ).also { contactUri -> holder.quickcontact?.assignContactUri(contactUri) } getString(photoDataIndex)?.also {photoData -> /* * Decodes the thumbnail file to a Bitmap. * The method loadContactPhotoThumbnail() is defined * in the section "Set the contact URI and thumbnail." */ loadContactPhotoThumbnail(photoData)?.also { thumbnailBitmap -> /* * Sets the image in the QuickContactBadge. * QuickContactBadge inherits from ImageView. */ holder.quickcontact?.setImageBitmap(thumbnailBitmap) } } } } } }
Java
private class ContactsAdapter extends CursorAdapter { private LayoutInflater inflater; ... public ContactsAdapter(Context context) { super(context, null, 0); /* * Gets an inflater that can instantiate * the ListView layout from the file */ inflater = LayoutInflater.from(context); ... } ... /** * Defines a class that holds 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 view references * in a ViewHolder class to prevent having to look * them up each time bindView() is called. */ final ContactListLayoutBinding binding = ContactListLayoutBinding.inflate(inflater, viewGroup, false); final ViewHolder holder = new ViewHolder(); holder.displayname = binding.displayName; holder.quickcontact = binding.quickContact; view.setTag(holder); return binding.root; } ... @Override public void bindView( View view, Context context, Cursor cursor) { final ViewHolder holder = (ViewHolder) view.getTag(); final String photoData = cursor.getString(photoDataIndex); final String displayName = cursor.getString(displayNameIndex); ... // Sets the display name in the layout holder.displayname = cursor.getString(displayNameIndex); ... /* * Generates a contact URI for the QuickContactBadge */ final Uri contactUri = Contacts.getLookupUri( cursor.getLong(idIndex), cursor.getString(lookupKeyIndex)); holder.quickcontact.assignContactUri(contactUri); String photoData = cursor.getString(photoDataIndex); /* * 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); }
הגדרת משתנים
בקוד, מגדירים משתנים, כולל הקרנה של Cursor
שכוללת את העמודות הנדרשות, כפי שמתואר בדוגמה הבאה.
הערה: קטעי הקוד הבאים משתמשים בשיטה loadContactPhotoThumbnail()
, שמוגדרת בקטע הגדרת ה-URI של איש הקשר והתמונה הממוזערת שלו.
Kotlin
/* * Defines a projection based on platform version. This ensures * that you retrieve the correct columns. */ private val PROJECTION: Array<out String> = arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ContactsContract.Contacts.DISPLAY_NAME_PRIMARY } else { ContactsContract.Contacts.DISPLAY_NAME }, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ContactsContract.Contacts.PHOTO_FILE_ID } else { /* * Although it's not necessary to include the * column twice, this keeps the number of * columns the same regardless of version */ ContactsContract.Contacts._ID } ) ... class ContactsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor> { ... // Defines a ListView private val listView: ListView? = null // Defines a ContactsAdapter private val adapter: ContactsAdapter? = null ... // Defines a Cursor to contain the retrieved data private val cursor: Cursor? = null /* * 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 val idIndex = 0 // Column index of the LOOKUP_KEY column private val lookupKeyIndex = 1 // Column index of the display name column private val displayNameIndex = 3 /* * Column index of the photo data column. * It's PHOTO_THUMBNAIL_URI for Honeycomb and later, * and _ID for previous versions. */ private val photoDataIndex: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 3 else 0 ...
Java
public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { ... // Defines a ListView private ListView listView; // Defines a ContactsAdapter private ContactsAdapter adapter; ... // Defines a Cursor to contain the retrieved data private Cursor cursor; /* * Defines a projection based on platform version. This ensures * that you retrieve the correct columns. */ private static final String[] PROJECTION = { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) ? ContactsContract.Contacts.PHOTO_FILE_ID : /* * Although it's not necessary to include the * column twice, this keeps the number of * columns the same regardless of version */ ContactsContract.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 idIndex = 0; // Column index of the LOOKUP_KEY column private int lookupKeyIndex = 1; // Column index of the display name column private int displayNameIndex = 3; /* * Column index of the photo data column. * It's PHOTO_THUMBNAIL_URI for Honeycomb and later, * and _ID for previous versions. */ private int photoDataIndex = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 3 : 0; ...
הגדרת ListView
ב-Fragment.onCreate()
, יוצרים את המתאם המותאם אישית של הסמן ומקבלים נקודת אחיזה אל ListView
:
Kotlin
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return FragmentListViewBinding.inflate(...).let { binding -> ... /* * Gets a handle to the ListView in the file * contact_list_layout.xml */ listView = binding.contactList mAdapter?.also { listView?.adapter = it } ... }.root } ...
Java
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { FragmentListViewBinding binding = FragmentListViewBinding.inflate(...) ... /* * Gets a handle to the ListView in the file * contact_list_layout.xml */ if (binding.contactListView != null && adapter != null) { binding.contactListView.setAdapter(adapter); } ... } ...
ב-onViewCreated()
, מקשרים את ContactsAdapter
ל-ListView
:
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) /* * Instantiates the subclass of * CursorAdapter */ mAdapter = activity?.let { ContactsAdapter(it).also { adapter -> // Sets up the adapter for the ListView listView?.adapter = adapter } } }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { ... /* * Instantiates the subclass of * CursorAdapter */ mAdapter = new ContactsAdapter(getActivity()); // Sets up the adapter for the ListView if (listView != null && mAdapter != null) { listView.setAdapter(mAdapter); } ... } ...
כשמקבלים Cursor
שמכיל את נתוני אנשי הקשר, בדרך כלל ב-onLoadFinished()
, צריך לקרוא ל-swapCursor()
כדי להעביר את נתוני Cursor
אל ListView
. הפונקציה מציגה את הערך של QuickContactBadge
לכל רשומה ברשימת אנשי הקשר.
Kotlin
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) { // When the loader has completed, swap the cursor into the adapter mAdapter?.swapCursor(cursor) }
Java
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // When the loader has completed, swap the cursor into the adapter mAdapter.swapCursor(cursor); }
כשמקשרים Cursor
ל-ListView
באמצעות CursorAdapter
(או תת-מחלקה), ומשתמשים ב-CursorLoader
כדי לטעון את ה-Cursor
, תמיד צריך לנקות את ההפניות ל-Cursor
בהטמעה של onLoaderReset()
.
הדוגמה הבאה ממחישה זאת:
Kotlin
override fun onLoaderReset(loader: Loader<Cursor>) { // Removes remaining reference to the previous Cursor adapter?.swapCursor(null) }
Java
@Override public void onLoaderReset(Loader<Cursor> loader) { // Removes remaining reference to the previous Cursor adapter.swapCursor(null); }