热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【AndroidDevelopersTraining】101.显示快

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。


注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。


原文链接:
http://developer.android.com/training/contacts-provider/display-contact-badge.html



这节课将会向你展示如何添加一个
QuickContactBadge
到你的UI中,以及如何将数据和它捆绑起来。一个
QuickContactBadge
是一个显示缩略图的空间。虽然你可以使用
Bitmap
显示任何缩略图,但是你必须要将联系人照片进行解码。


缩略图的作用类似于一个控制器:当用户点击缩略图时,
QuickContactBadge
会扩展成一个对话框,其中包含如下内容:





一个放大的图标



一个和该联系人关联的大图标,如果没有的话,就用一个默认的占位图片代替。



应用图标



每一个具体的联系人信息旁会有一个应用图标,它说明该数据可被此内置应用处理。例如,如果联系人的数据中有一个或多个email地址,那么就会出现一个email的图标。当用户点击这个图标,联系人的所有email地址会显示出来,之后用户如果点击了某一个email地址,会打开电子邮件应用,其中的收件人地址就是所选中的email地址。


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
对象。你从Contacts Provider搜索的列数据用来创建内容URI和
Bitmap
对象。指定这些列左右你在
Cursor
中用来加载数据的投影的一部分。


对Android 3.0(API版本11)及之后的版本,在你的投影中包含下面几列:







  • Contacts._ID












  • Contacts.LOOKUP_KEY












  • Contacts.PHOTO_THUMBNAIL_URI








对Android 2.3.3(API版本10)及之前的版本,在你的投影中包含下面几列:






  • Contacts._ID










  • Contacts.LOOKUP_KEY







我们假设在这节课之前,你已经加载了一个
Cursor
,它包含了上面的这些列,还有一些你已经选择了的列。要学习如何使用
Cursor
检索这些列数据,可以参阅:
Retrieving a List of Contacts
(博客链接:
http://www.cnblogs.com/jdneo/p/3674830.html







三). 设置内容URI和缩略图



一旦你有了必要的列,你就可以将数据绑定到
QuickContactBadge
上。




设置内容URI



要为联系人的内容URI,调用
getLookupUri(id,lookupKey)
来获取一个
CONTENT_LOOKUP_URI
,然后调用
assignContactUri()
来设置联系人。例如:



//


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



当用户点击了
QuickContactBadge
图标后,联系人的详细信息会自动显示在对话框中。




设置照片缩略图




QuickContactBadge
设置联系人的URI并不会自动的加载他的照片。要加载照片,需要从联系人的
Cursor
行中获取照片的URI,使用它来打开包含有压缩后的照片缩略图文件,并将该文件读入一个
Bitmap
对象。




Note:




PHOTO_THUMBNAIL_URI

列在Android 3.0之前的版本中是没有的。对于那些较早的版本,你必须从

Contacts.Photo

自表中获取URI。


首先,为访问包含有
Contacts._ID

Contacts.LOOKUP_KEY
列的
Cursor
设置变量,如下所示:



//


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



定义一个方法,它获取联系人的照片数据,以及缩略图的目标大小,并将照片以一个适当尺寸的
Bitmap
形式返回。我们首先从构造一个指向该缩略图的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


;
}



在你的代码中调用


loadContactPhotoThumbnail()

来获取缩略图的

Bitmap

对象,将结果用来设置你的

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
是一个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
绑定到一个包含有
QuickContactBadge

ListView
上,自定义一个自定义的适配器,它继承自
CursorAdapter
。这一方法允许你在将
Cursor
绑定到
QuickContactBadge
之前,可以在
Cursor
内处理数据。同时这个方法还允许你将多个
Cursor
列绑定到
QuickContactBadge
上。这些方法对于一个传统的
CursorAdapter
而言是不可能做到的。




对于
CursorAdapter
的子类,你必须覆写下列方法:


CursorAdapter.newView()


填充一个新的
View
对象来显示列表项布局。在该方法的覆写版本中,保存布局中子
View
对象的句柄,包括子
QuickContactBadge
。通过使用这一方法,你可以避免每次你填充一个新的布局时去获取子
View
对象的句柄。


你必须要覆写这一方法,这样你才能获取每个自
View
对象的句柄。这一方法允许你在
CursorAdapter.bindView()
方法中控制他们的捆绑关系。


CursorAdapter.bindView()


将数据从当前的
Cursor
行移动到列表项布局中子
View
对象里。你必须覆写这一方法这样你就能同时将联系人URI和缩略图捆绑到
QuickContactBadge
上。而默认的实现值允许一列数据和一个
View
间一对一的对应关系。


下面的代码片段包含了自定义子类
CursorAdapter
的一个例子:




定义自定义列表适配器



定义
CursorAdapter
的子类,包括它的构造函数,覆写
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);
}






设置变量



在你的代码中,设置变量,包括一个
Cursor
投影,它包含了必要的那些列。




Note:



下面的代码片段使用了


loadContactPhotoThumbnail()

方法,这在之前的章节中该方法已经详细叙述过了。



例如:



public


class

ContactsFragment

extends

Fragment

implements



LoaderManager.LoaderCallbacks



{
...


//


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

;
...




设置ListView




Fragment.onCreate()
中,实例化自定义的

cursor适配器,并获得一个

ListView

的句柄:




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





当你获取了一个包含有联系人数据的

Cursor

,通常是在
, D)">
onLoadFinished()

,调用

swapCursor()



Cursor

数据移动到

ListView

。这会为联系人列表中的每一个条目显示

QuickContactBadge







public


void

onLoadFinished(Loader

loader, Cursor cursor) {



//


When the loader has completed, swap the cursor into the adapter.


mContactsAdapter.swapCursor(cursor);
}





当你通过一个

CursorAdapter

(或它的子类)将一个



Cursor


绑定到


ListView


上,并且你使用


CursorLoader


加载


Cursor


,一定要记得在

)">
onLoaderReset()


的实现中清楚


Cursor


的引用,例如:








@Override


public


void

onLoaderReset(Loader

loader) {



//


Removes remaining reference to the previous Cursor

mContactsAdapter.swapCursor(

null


);
}



【Android Developers Training】 101. 显示快速联系人挂件(Quick Contact Badge)




推荐阅读
author-avatar
emddh989
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有