Trang này cho bạn biết cách thêm QuickContactBadge
vào giao diện người dùng và cách liên kết dữ liệu với giao diện đó. QuickContactBadge
là một tiện ích ban đầu xuất hiện dưới dạng hình thu nhỏ. Mặc dù bạn có thể sử dụng Bitmap
bất kỳ cho hình thu nhỏ, nhưng bạn thường dùng Bitmap
được giải mã từ hình thu nhỏ ảnh của người liên hệ.
Hình ảnh nhỏ đóng vai trò là một mục điều khiển. Khi người dùng nhấn vào hình ảnh đó, QuickContactBadge
sẽ mở rộng thành một hộp thoại chứa thông tin sau:
- Hình ảnh lớn
- Hình ảnh lớn liên kết với người liên hệ đó hoặc nếu không có hình ảnh nào, hãy chọn hình ảnh phần giữ chỗ.
- Biểu tượng ứng dụng
- Một biểu tượng ứng dụng cho từng phần dữ liệu chi tiết mà một ứng dụng tích hợp sẵn có thể xử lý. Ví dụ: nếu thông tin của người liên hệ có một hoặc nhiều địa chỉ email, thì một biểu tượng email sẽ xuất hiện. Khi người dùng nhấn vào biểu tượng này, tất cả địa chỉ email của người liên hệ sẽ xuất hiện. Khi người dùng nhấn vào một trong các địa chỉ, ứng dụng email sẽ hiển thị màn hình để soạn thư gửi đến địa chỉ email đã chọn.
Khung hiển thị QuickContactBadge
cho phép truy cập tức thì vào thông tin của một mục liên hệ và một cách nhanh chóng để giao tiếp với mục liên hệ đó. Người dùng không phải tra cứu một người liên hệ, tìm và sao chép thông tin rồi dán vào ứng dụng thích hợp. Thay vào đó, họ có thể nhấn vào QuickContactBadge
, chọn phương thức liên lạc mà họ muốn sử dụng và trực tiếp gửi thông tin của phương thức đó đến ứng dụng thích hợp.
Thêm chế độ xem QuickContacthuy
Để thêm QuickContactBadge
, hãy chèn phần tử <QuickContactBadge>
vào bố cục của bạn, như trong ví dụ sau:
<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>
Truy xuất dữ liệu của nhà cung cấp
Để hiển thị một người liên hệ trong QuickContactBadge
, bạn cần có URI nội dung cho người liên hệ đó và Bitmap
cho hình ảnh nhỏ. Bạn tạo cả URI nội dung và Bitmap
từ các cột được truy xuất từ Trình cung cấp danh bạ. Hãy chỉ định các cột này trong phép chiếu mà bạn sử dụng để tải dữ liệu vào Cursor
.
Đối với Android 3.0 (API cấp 11) trở lên, hãy đưa các cột sau vào phép chiếu của bạn:
Đối với Android 2.3.3 (API cấp 10) trở xuống, hãy sử dụng các cột sau:
Các ví dụ trên trang này giả định rằng một Cursor
chứa các cột này và mọi cột đã chọn khác đã được tải. Để tìm hiểu cách truy xuất các cột trong Cursor
, hãy xem phần Truy xuất danh sách người liên hệ.
Đặt URI liên hệ và hình thu nhỏ
Sau khi có các cột cần thiết, bạn có thể liên kết dữ liệu với QuickContactBadge
.
Đặt URI liên hệ
Để đặt URI nội dung cho địa chỉ liên hệ đó, hãy gọi getLookupUri(id,lookupKey)
để nhận CONTENT_LOOKUP_URI
, sau đó gọi assignContactUri()
để đặt địa chỉ liên hệ đó. Lệnh này được minh hoạ trong ví dụ sau:
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);
Khi người dùng nhấn vào biểu tượng QuickContactBadge
, thông tin chi tiết của người liên hệ đó sẽ xuất hiện trong hộp thoại.
Đặt hình thu nhỏ của ảnh
Việc đặt URI người liên hệ cho QuickContactBadge
sẽ không tự động
tải ảnh thu nhỏ của người liên hệ đó. Để tải ảnh, hãy lấy URI cho ảnh qua hàng Cursor
của người liên hệ, sử dụng URI này để mở tệp chứa ảnh hình thu nhỏ nén và đọc tệp đó trong Bitmap
.
Lưu ý: Cột PHOTO_THUMBNAIL_URI
không có trong các phiên bản nền tảng trước phiên bản 3.0. Đối với các phiên bản đó, bạn phải truy xuất URI qua bảng phụ Contacts.Photo
.
Trước tiên, hãy thiết lập các biến để truy cập vào Cursor
chứa các cột Contacts._ID
và 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); ...
Xác định phương thức lấy dữ liệu liên quan đến ảnh cho người liên hệ và kích thước của khung hiển thị đích đến rồi trả về hình thu nhỏ có kích thước phù hợp trong Bitmap
. Bắt đầu bằng cách tạo URI trỏ đến hình thu nhỏ:
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; }
Gọi phương thức loadContactPhotoThumbnail()
trong mã để lấy hình thu nhỏ Bitmap
và sử dụng kết quả này để đặt hình thu nhỏ của ảnh trong 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);
Thêm QuickContacthuy vào ListView
QuickContactBadge
là một phần bổ sung hữu ích cho ListView
hiển thị danh sách các liên hệ. Sử dụng QuickContactBadge
để hiển thị ảnh thu nhỏ cho mỗi người liên hệ. Khi người dùng nhấn vào hình thu nhỏ đó, hộp thoại QuickContactBadge
sẽ xuất hiện.
Thêm phần tử QuickContacthuy
Để bắt đầu, hãy thêm một phần tử thành phần hiển thị QuickContactBadge
vào bố cục mục. Ví dụ: nếu bạn muốn hiển thị QuickContactBadge
và tên cho mỗi mục liên hệ mà bạn truy xuất, hãy đặt XML sau vào tệp bố cục:
<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>
Trong các phần sau, tệp này được gọi là contact_item_layout.xml
.
Thiết lập CursorAdapter tuỳ chỉnh
Để liên kết CursorAdapter
với ListView
có chứa QuickContactBadge
, hãy xác định một trình chuyển đổi tuỳ chỉnh
mở rộng CursorAdapter
. Phương pháp này cho phép bạn xử lý dữ liệu trong Cursor
trước khi liên kết dữ liệu đó với QuickContactBadge
. Phương pháp này cũng cho phép bạn liên kết nhiều cột Cursor
với QuickContactBadge
. Không có hoạt động nào trong số này không thực hiện được trong CursorAdapter
thông thường.
Lớp con của CursorAdapter
mà bạn xác định phải ghi đè các phương thức sau:
CursorAdapter.newView()
-
Tăng cường một đối tượng
View
mới để giữ bố cục mục. Trong chế độ ghi đè của phương thức này, hãy lưu trữ ô xử lý cho các đối tượngView
con của bố cục, bao gồm cảQuickContactBadge
con. Bằng cách áp dụng phương pháp này, bạn tránh được việc phải xử lý các đối tượngView
con mỗi khi tăng cường một bố cục mới.Bạn phải ghi đè phương thức này để có thể xử lý từng đối tượng
View
con. Kỹ thuật này cho phép bạn kiểm soát việc liên kết các nội dung đó trongCursorAdapter.bindView()
. CursorAdapter.bindView()
-
Di chuyển dữ liệu từ hàng
Cursor
hiện tại sang các đối tượng conView
của bố cục mục. Bạn phải ghi đè phương thức này để có thể liên kết cả URI và hình thu nhỏ của địa chỉ liên hệ vớiQuickContactBadge
. Cách triển khai mặc định chỉ cho phép liên kết một với một giữa một cột vàView
.
Đoạn mã sau đây chứa ví dụ về một lớp con tuỳ chỉnh của CursorAdapter
:
Xác định bộ chuyển đổi danh sách tuỳ chỉnh
Xác định lớp con của CursorAdapter
, bao gồm cả hàm khởi tạo, đồng thời ghi đè newView()
và 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); }
Thiết lập biến
Trong mã của bạn, hãy thiết lập các biến bao gồm một phép chiếu Cursor
bao gồm các cột cần thiết, như trong ví dụ sau.
Lưu ý: Các đoạn mã sau đây sử dụng phương thức loadContactPhotoThumbnail()
. Phương thức này được xác định trong phần Thiết lập URI liên hệ và hình thu nhỏ.
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; ...
Thiết lập ListView
Trong Fragment.onCreate()
, hãy tạo thực thể cho bộ chuyển đổi con trỏ tuỳ chỉnh và xử lý 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); } ... } ...
Trong onViewCreated()
, hãy liên kết ContactsAdapter
với 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); } ... } ...
Khi bạn quay lại Cursor
chứa dữ liệu danh bạ, thường là trong onLoadFinished()
, hãy gọi swapCursor()
để di chuyển dữ liệu Cursor
sang ListView
. Thao tác này sẽ hiển thị QuickContactBadge
cho từng mục trong danh sách người liên hệ.
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); }
Khi bạn liên kết Cursor
với ListView
bằng CursorAdapter
(hoặc lớp con) và sử dụng CursorLoader
để tải Cursor
, hãy luôn xoá các tham chiếu đến Cursor
trong quá trình triển khai onLoaderReset()
.
Lệnh này được minh hoạ trong ví dụ sau:
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); }