鍍金池/ 教程/ Android/ 顯示聯(lián)系人頭像
檢測(cè)常用的手勢(shì)
優(yōu)化layout的層級(jí)
用戶輸入
管理應(yīng)用的內(nèi)存
聯(lián)系人信息
開(kāi)發(fā)輔助程序
Android多媒體
添加語(yǔ)音功能
顯示位置地址
提供向下與橫向?qū)Ш?/span>
支持游戲控制器
訪問(wèn)可穿戴數(shù)據(jù)層
處理多點(diǎn)觸控手勢(shì)
全屏沉浸式應(yīng)用
為多線程創(chuàng)建管理器
數(shù)據(jù)保存
Intent的發(fā)送
更新Notification
優(yōu)化下載以高效地訪問(wèn)網(wǎng)絡(luò)
打印
打包可穿戴應(yīng)用
接收從其他App傳送來(lái)的數(shù)據(jù)
發(fā)送與接收消息
建立靈活動(dòng)態(tài)的UI
處理鍵盤輸入
Building a Work Policy Controller
建立測(cè)試環(huán)境
創(chuàng)建表盤
分享文件
顯示Notification進(jìn)度
實(shí)現(xiàn)自適應(yīng)UI流(Flows)
使用設(shè)備管理策略增強(qiáng)安全性
使用能感知版本的組件
執(zhí)行網(wǎng)絡(luò)操作
建立文件分享
添加移動(dòng)
更新你的Security Provider來(lái)對(duì)抗SSL漏洞利用
支持鍵盤導(dǎo)航
創(chuàng)建和監(jiān)視地理圍欄
發(fā)送并同步數(shù)據(jù)
使用BigView樣式
無(wú)線連接設(shè)備
提供向上導(dǎo)航與歷史導(dǎo)航
最小化定期更新造成的影響
實(shí)現(xiàn)向下的導(dǎo)航
支持不同的屏幕大小
Android 可穿戴應(yīng)用
添加動(dòng)畫(huà)
顯示聯(lián)系人頭像
使用OpenGL ES顯示圖像
處理輸入法可見(jiàn)性
分享文件
保持設(shè)備喚醒
淡化系統(tǒng)Bar
使用NFC分享文件
保存到Preference
Android聯(lián)系人信息與位置信息
創(chuàng)建標(biāo)準(zhǔn)的網(wǎng)絡(luò)請(qǐng)求
使用Drawables
管理Bitmap的內(nèi)存使用
管理Activity的生命周期
按需加載視圖
傳輸資源
為可穿戴設(shè)備創(chuàng)建自定義UI
在一個(gè)線程中執(zhí)行一段特定的代碼
性能優(yōu)化
隱藏導(dǎo)航欄
創(chuàng)建目錄瀏覽器
為多種大小的屏幕進(jìn)行規(guī)劃
View間漸變
使用觸摸手勢(shì)
高效加載大圖
使用CursorLoader在后臺(tái)加載數(shù)據(jù)
創(chuàng)建抽屜式導(dǎo)航(navigation drawer)
管理音頻焦點(diǎn)
創(chuàng)建后臺(tái)服務(wù)
創(chuàng)建功能測(cè)試
創(chuàng)建使用Material Design的應(yīng)用
停止與重啟Activity
添加一個(gè)簡(jiǎn)便的分享功能
啟動(dòng)Activity時(shí)保留導(dǎo)航
TV應(yīng)用清單
創(chuàng)建向后兼容的UI
?# 優(yōu)化自定義View
創(chuàng)建單元測(cè)試
在UI上顯示Bitmap
建立OpenGL ES的環(huán)境
構(gòu)建表盤服務(wù)
JNI Tips
建立搜索界面
實(shí)現(xiàn)自定義View的繪制
使用HTTPS與SSL
按需操控BroadcastReceiver
分享簡(jiǎn)單的數(shù)據(jù)
繪制形狀
Android位置信息
創(chuàng)建并運(yùn)行可穿戴應(yīng)用
執(zhí)行 Sync Adpater
獲取最后可知位置
創(chuàng)建 Android 項(xiàng)目
實(shí)現(xiàn)高效的導(dǎo)航
退出全屏的Activity
創(chuàng)建Card
兼容音頻輸出設(shè)備
同步數(shù)據(jù)單元
傳輸數(shù)據(jù)時(shí)避免消耗大量電量
保存到文件
緩存Bitmap
提供配置 Activity
調(diào)度重復(fù)的鬧鐘
實(shí)現(xiàn)輔助功能
重復(fù)的下載是冗余的
隱藏狀態(tài)欄
實(shí)現(xiàn)自定義的網(wǎng)絡(luò)請(qǐng)求
規(guī)劃界面和他們之間的關(guān)系
使用Sync Adapter傳輸數(shù)據(jù)
TV應(yīng)用內(nèi)搜索
響應(yīng)觸摸事件
使用Google Cloud Messaging(已廢棄)
控制相機(jī)
Android網(wǎng)絡(luò)連接與云服務(wù)
請(qǐng)求分享一個(gè)文件
處理TV硬件
響應(yīng)UI可見(jiàn)性的變化
使用網(wǎng)絡(luò)服務(wù)發(fā)現(xiàn)
指定輸入法類型
優(yōu)化電池壽命
創(chuàng)建TV應(yīng)用
獲取聯(lián)系人列表
拖拽與縮放
啟動(dòng)與停止線程池中的線程
創(chuàng)建 Sync Adpater
使用 WiFi P2P 服務(wù)發(fā)現(xiàn)
開(kāi)始使用Material Design
代理至新的APIs
使用include標(biāo)簽重用layouts
使得View可交互
高效顯示Bitmap
創(chuàng)建企業(yè)級(jí)應(yīng)用
Fragments之間的交互
創(chuàng)建與執(zhí)行測(cè)試用例
綜合:設(shè)計(jì)我們的樣例 App
繪制表盤
建立簡(jiǎn)單的用戶界面
自定義動(dòng)畫(huà)
開(kāi)發(fā)輔助服務(wù)
避免出現(xiàn)程序無(wú)響應(yīng)ANR(Keeping Your App Responsive)
使用ViewPager實(shí)現(xiàn)屏幕滑動(dòng)
設(shè)計(jì)高效的導(dǎo)航
Android分享操作(Building Apps with Content Sharing)
提供向后的導(dǎo)航
保持向下兼容
創(chuàng)建TV播放應(yīng)用
縮放View
使用 WiFi 建立 P2P 連接
Android后臺(tái)任務(wù)
連接到網(wǎng)絡(luò)
為 Notification 添加頁(yè)面
使TV應(yīng)用是可被搜索的
添加Action Bar
使用Material的主題
啟動(dòng)另一個(gè)Activity
顯示正在播放卡片
適配不同的系統(tǒng)版本
輕松錄制視頻
創(chuàng)建可穿戴的應(yīng)用
創(chuàng)建自定義的布局
重新創(chuàng)建Activity
使用CursorLoader執(zhí)行查詢?nèi)蝿?wù)
使用舊的APIs實(shí)現(xiàn)新API的效果
使用備份API
安全要點(diǎn)
Android入門基礎(chǔ):從這里開(kāi)始
保存并搜索數(shù)據(jù)
根據(jù)網(wǎng)絡(luò)連接類型來(lái)調(diào)整下載模式
使用Tabs創(chuàng)建Swipe視圖
SMP(Symmetric Multi-Processor) Primer for Android
解析 XML 數(shù)據(jù)
使用 Volley 傳輸網(wǎng)絡(luò)數(shù)據(jù)
建立ActionBar
Android交互設(shè)計(jì)
使用Intent修改聯(lián)系人信息
增加搜索功能
輕松拍攝照片
定義形狀
測(cè)試你的Activity
在 Notifcation 中接收語(yǔ)音輸入
與其他應(yīng)用的交互
管理系統(tǒng)UI
追蹤手勢(shì)移動(dòng)
Android界面設(shè)計(jì)
執(zhí)行 Android 程序
顯示確認(rèn)界面
創(chuàng)建Lists與Cards
打印HTML文檔
創(chuàng)建TV應(yīng)用
為多屏幕設(shè)計(jì)
定義Shadows與Clipping視圖
使用Fragment建立動(dòng)態(tài)UI
接收Activity返回的結(jié)果
布局變更動(dòng)畫(huà)
定位常見(jiàn)的問(wèn)題
自定義ActionBar的風(fēng)格
定義Layouts
發(fā)送簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求
啟動(dòng)與銷毀Activity
與UI線程通信
非UI線程處理Bitmap
創(chuàng)建TV布局
提升Layout的性能
報(bào)告任務(wù)執(zhí)行狀態(tài)
判斷并監(jiān)測(cè)網(wǎng)絡(luò)連接狀態(tài)
兼容不同的設(shè)備
處理按鍵動(dòng)作
優(yōu)化性能和電池使用時(shí)間
給其他App發(fā)送簡(jiǎn)單的數(shù)據(jù)
Implementing App Restrictions
向后臺(tái)服務(wù)發(fā)送任務(wù)請(qǐng)求
展示Card翻轉(zhuǎn)動(dòng)畫(huà)
管理ViewGroup中的觸摸事件
兼容不同的屏幕密度
通過(guò)藍(lán)牙進(jìn)行調(diào)試
為可穿戴設(shè)備創(chuàng)建Notification
控制音量與音頻播放
獲取聯(lián)系人詳情
在表盤上顯示信息
提供向上的導(dǎo)航
滾動(dòng)手勢(shì)動(dòng)畫(huà)
幫助用戶在TV上找到內(nèi)容
創(chuàng)建TV導(dǎo)航
為索引指定App內(nèi)容
ActionBar的覆蓋疊加
Android Wear 上的位置檢測(cè)
保護(hù)安全與隱私的最佳策略
Ensuring Compatibility with Managed Profiles
解決云同步的保存沖突
獲取位置更新
創(chuàng)建List
測(cè)試程序
管理網(wǎng)絡(luò)的使用情況
為App內(nèi)容開(kāi)啟深度鏈接
推薦TV內(nèi)容
建立一個(gè)Notification
管理音頻播放
設(shè)計(jì)表盤
拍照
處理控制器輸入動(dòng)作
判斷并監(jiān)測(cè)設(shè)備的底座狀態(tài)與類型
處理查詢的結(jié)果
保存到數(shù)據(jù)庫(kù)
支持多個(gè)游戲控制器
創(chuàng)建 Stub Content Provider
使得ListView滑動(dòng)順暢
處理數(shù)據(jù)層的事件
創(chuàng)建TV應(yīng)用的第一步
使得你的App內(nèi)容可被Google搜索
將 Notification 放成一疊
創(chuàng)建 Stub 授權(quán)器
暫停與恢復(fù)Activity
管理設(shè)備的喚醒狀態(tài)
Android圖像與動(dòng)畫(huà)
打印照片
云同步
創(chuàng)建TV直播應(yīng)用
為Notification賦加可穿戴特性
提供一個(gè)Card視圖
建立請(qǐng)求隊(duì)列(RequestQueue)
適配不同的語(yǔ)言
創(chuàng)建詳情頁(yè)
測(cè)試UI組件
接收其他設(shè)備的文件
創(chuàng)建自定義View
建立第一個(gè)App
創(chuàng)建2D Picker
監(jiān)測(cè)電池的電量與充電狀態(tài)
打印自定義文檔
抽象出新的APIs
通知提示用戶
獲取文件信息
運(yùn)用投影與相機(jī)視角
在IntentService中執(zhí)行后臺(tái)任務(wù)
多線程操作
創(chuàng)建一個(gè)Fragment
添加Action按鈕
在不同的 Android 系統(tǒng)版本支持控制器
維護(hù)兼容性
發(fā)送文件給其他設(shè)備
創(chuàng)建TV游戲應(yīng)用
創(chuàng)建自定義的View類
代碼性能優(yōu)化建議
Intent過(guò)濾
適配不同的屏幕

顯示聯(lián)系人頭像

編寫:spencer198711 - 原文:http://developer.android.com/training/contacts-provider/display-contact-badge.html

這一課展示了如何在我們的應(yīng)用界面上添加一個(gè)[QuickContactBadge](),以及如何為它綁定數(shù)據(jù)。 QuickContactBadge是一個(gè)在初始情況下顯示聯(lián)系人縮略圖頭像的widget。盡管我們可以使用任何Bitmap作為縮略圖頭像,但是我們通常會(huì)使用從聯(lián)系人照片縮略圖中解碼出來(lái)的Bitmap。

這個(gè)小的圖片是一個(gè)控件,當(dāng)用戶點(diǎn)擊它時(shí),QuickContactBadge會(huì)展開(kāi)一個(gè)包含以下內(nèi)容的對(duì)話框:

  • 一個(gè)大的聯(lián)系人頭像

    與這個(gè)聯(lián)系人關(guān)聯(lián)的大的頭像,如果此人沒(méi)有設(shè)置頭像,則顯示預(yù)留的圖案。

  • 應(yīng)用程序圖標(biāo)

    根據(jù)聯(lián)系人詳情數(shù)據(jù),顯示每一個(gè)能夠被手機(jī)中的應(yīng)用所處理的數(shù)據(jù)的圖標(biāo)。例如,如果聯(lián)系人的數(shù)據(jù)包含一個(gè)或多個(gè)email地址,就會(huì)顯示email應(yīng)用的圖標(biāo)。當(dāng)用戶點(diǎn)擊這個(gè)圖標(biāo)的時(shí)候,這個(gè)聯(lián)系人所有的email地址都會(huì)顯示出來(lái)。當(dāng)用戶點(diǎn)擊其中一個(gè)email地址時(shí),email應(yīng)用將會(huì)顯示一個(gè)界面,讓用戶為選中的地址撰寫郵件。

QuickContactBadge視圖提供了對(duì)聯(lián)系人數(shù)據(jù)的即時(shí)訪問(wèn),是一種與聯(lián)系人溝通的快捷方式。用戶不用查詢一個(gè)聯(lián)系人,查找并復(fù)制信息,然后把信息粘貼到合適的應(yīng)用中。他們可以點(diǎn)擊QuickContactBadge,選擇他們想要的溝通方式,然后直接把信息發(fā)送給合適的應(yīng)用中。

添加一個(gè)QuickContactBadge視圖

為了添加一個(gè)QuickContactBadge視圖,需要在布局文件中插入一個(gè)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>

獲取Contacts Provider的數(shù)據(jù)

為了能在QuickContactBadge中顯示聯(lián)系人,我們需要這個(gè)聯(lián)系人的內(nèi)容URI和顯示頭像的Bitmap。我們可以從在Contacts Provider中獲取到的數(shù)據(jù)列中生成這兩個(gè)數(shù)據(jù)。需要指定這些列作為查詢映射去把數(shù)據(jù)加載到Cursor中。

對(duì)于Android 3.0(API版本為11)以及以后的版本,需要在查詢映射中添加以下列:

對(duì)于Android 2.3.3(API版本為10)以及之前的版本,則使用以下列:

這一課的剩余部分假設(shè)你已經(jīng)獲取到了包含這些以及其他你可能選擇的數(shù)據(jù)列的Cursor對(duì)象。想要學(xué)習(xí)如何獲取這些列對(duì)象的Cursor,請(qǐng)參閱課程獲取聯(lián)系人列表。

設(shè)置聯(lián)系人URI和縮略圖

一旦我們已經(jīng)擁有了所需的數(shù)據(jù)列,那么我們就可以為QuickContactBadge視圖綁定數(shù)據(jù)了。

設(shè)置聯(lián)系人URI

為了設(shè)置聯(lián)系人URI,需要調(diào)用[getLookupUri(id, lookupKey)]()去獲取CONTENT_LOOKUP_URI,然后調(diào)用assignContactUri()去為QuickContactBadge設(shè)置對(duì)應(yīng)的聯(lián)系人。例如:

// 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);

當(dāng)用戶點(diǎn)擊QuickContactBadge圖標(biāo)的時(shí)候,這個(gè)聯(lián)系人的詳細(xì)信息將會(huì)自動(dòng)展現(xiàn)在對(duì)話框中。

設(shè)置聯(lián)系人照片的縮略圖

為QuickContactBadge設(shè)置聯(lián)系人URI并不會(huì)自動(dòng)加載聯(lián)系人的縮略圖照片。為了加載聯(lián)系人照片,需要從聯(lián)系人的Cursor對(duì)象的一行數(shù)據(jù)中獲取照片的URI,使用這個(gè)URI去打開(kāi)包含壓縮的縮略圖文件,并把這個(gè)文件讀到Bitmap對(duì)象中。

Note:PHOTO_THUMBNAIL_URI這一列在Android 3.0之前的版本是不存在的。對(duì)于這些版本,我們必須從Contacts.Photo表中獲取照片的URI。

首先,為包含Contacts._ID和Contacts.LOOKUP_KEY的Cursor數(shù)據(jù)列設(shè)置對(duì)應(yīng)的變量,這在之前已經(jīng)有描述:

// 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);
...

定義一個(gè)方法,使用與這個(gè)聯(lián)系人的照片有關(guān)的數(shù)據(jù)和目標(biāo)視圖的尺寸作為參數(shù),返回一個(gè)尺寸合適的縮略圖Bitmap對(duì)象。下面先構(gòu)建一個(gè)指向這個(gè)縮略圖的URI:

 /**
 * 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;
}

在代碼中調(diào)用loadContactPhotoThumbnail()去獲取縮略圖Bitmap對(duì)象,使用獲取的Bitmap對(duì)象去設(shè)置QuickContactBadge頭像縮略圖。

...
/*
 * 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);

把QuickContactBadge添加到ListView

QuickContactBadge對(duì)于一個(gè)展示聯(lián)系人列表的ListView來(lái)說(shuō)是一個(gè)非常有用的添加功能。使用QuickContactBadge去為每一個(gè)聯(lián)系人顯示一個(gè)縮略圖,當(dāng)用戶點(diǎn)擊這個(gè)縮略圖時(shí),QuickContactBadge對(duì)話框?qū)?huì)顯示。

為L(zhǎng)istView添加QuickContactBadge

首先,在列表項(xiàng)布局文件中添加QuickContactBadge視圖元素。例如,如果我們想為獲取到的每一個(gè)聯(lián)系人顯示QuickContactBadge和名字,把以下的XML內(nèi)容放到對(duì)應(yīng)的布局文件中:

<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>

在以下的章節(jié)中,這個(gè)文件被稱為contact_item_layout.xml。

設(shè)置自定義的CursorAdapter

定義一個(gè)繼承自CursorAdapter的adapter來(lái)將CursorAdapter綁定到一個(gè)包含QuickContactBadge的ListView中。這種方式允許我們?cè)诮壎〝?shù)據(jù)到QuickContactBadge之前對(duì)Cursor中的數(shù)據(jù)進(jìn)行處理。同時(shí)也能將多個(gè)Cursor中的列綁定到QuickContactBadge。而使用普通的CursorAdapter是不能完成這些操作的。

我們定義的CursorAdapter的子類必須重寫以下方法:

*[CursorAdapter.newView()]()

填充一個(gè)View對(duì)象去持有列表項(xiàng)布局。在重寫這個(gè)方法的過(guò)程中,需要保存這個(gè)布局的子View的handles,包括QuickContactBadge的handles。通過(guò)采用這種方法,避免了每次在填充新的布局時(shí)都去獲取子View的handles。

我們必須重寫這個(gè)方法以便能夠獲取每個(gè)子View對(duì)象的handles。這種方法允許我們控制這些子View對(duì)象在CursorAdapter.bindView()方法中的綁定。
  • [CursorAdapter.bindView()]()

    將數(shù)據(jù)從當(dāng)前Cursor行綁定到列表項(xiàng)布局的子View對(duì)象中。必須重寫這個(gè)方法以便能夠?qū)⒙?lián)系人的URI和縮略圖信息綁定到QuickContactBadge。這個(gè)方法的默認(rèn)實(shí)現(xiàn)僅僅允許在數(shù)據(jù)列和View之間的一對(duì)一映射。

以下的代碼片段是一個(gè)包含了自定義CursorAdapter子類的例子。

定義自定義的列表Adapter

定義CursorAdapter的子類包括編寫這個(gè)類的構(gòu)造方法,以及重寫newView()和bindView():

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);
}

設(shè)置變量

在代碼中,設(shè)置相關(guān)變量,添加一個(gè)包括必須數(shù)據(jù)列的Cursor。

Note:以下的代碼片段使用了方法loadContactPhotoThumbnail(),這個(gè)方法是在設(shè)置聯(lián)系人URI和縮略圖那一節(jié)中定義的。

例如:

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;
...

設(shè)置ListView

Fragment.onCreate()方法中,實(shí)例化自定義的adapter對(duì)象,獲得一個(gè)ListView的handle。

@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);
    ...
}
...

onActivityCreated()方法中,將ContactsAdapter綁定到ListView。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    ...
    // Sets up the adapter for the ListView
    mListView.setAdapter(mAdapter);
    ...
}
...

當(dāng)獲取到一個(gè)包含聯(lián)系人數(shù)據(jù)的Cursor時(shí)(通常在onLoadFinished()的時(shí)候),調(diào)用swapCursor()把Cursor中的數(shù)據(jù)綁定到ListView。這將會(huì)為聯(lián)系人列表中的每一項(xiàng)都顯示一個(gè)QuickContactBadge。

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    // When the loader has completed, swap the cursor into the adapter.
    mContactsAdapter.swapCursor(cursor);
}

當(dāng)我們使用CursorAdapter或其子類中將Cursor中的數(shù)據(jù)綁定到ListView,并且使用了CursorLoader去加載Cursor數(shù)據(jù)時(shí),記得要在onLoaderReset()方法的實(shí)現(xiàn)中清理對(duì)Cursor對(duì)象的引用。例如:

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    // Removes remaining reference to the previous Cursor
    mContactsAdapter.swapCursor(null);
}