本文主要是介绍安卓用QuickContactBadge和AsyncQueryHandler实现联系人列表的完美实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在公司开发这么久了,发现好多的控件没有用过,然后发现了一些新的知识感觉还是很不错的,今天在这里我就来用一下QuickContactBadge的控件和AsyncQueryHandler,说到底QuickContactBadge这个控件我也是偶然发现的,然后乘着现在公司的工作不忙,然后也准备换工作温习一下知识点罢了。
一、介绍QuickContactBadge用法
1、 先看一下它的结构
implements View.OnClickListener
↳ android.view.View.imageView
↳ android.widget.QuickContactBadge
2、看下QuickContactBadge的使用方法和介绍
public void assignContactFromEmail (String emailAddress, boolean lazyLookup);
//指定联系人的电子邮箱地址。(注:它会先搜索这个号码,如果没有会提醒你是否添加到联系人
如果设置为true,将不//会立即查找这个邮箱地址,直到View被点击时。(注:是否延迟匹配电子邮件)
//参数 : emailAddress:联系人的电子邮箱地址lazyLookup:
(2)电话的调用
public void assignContactFromPhone (String phoneNumber, boolean lazyLookup)//为联系人指定一个电话号码</span></div>//参数
//phoneNumber : 联系人的电话号码
//lazyLookup : 如果设置为true,将不会立即查找这个电话号码,直到View被点击时。
public void assignContactUri(Uri contactUri)
//这方法用得比较多,指定一个uri
public void setMode(int size) ;//设计它的模式好像是3种(MODE_SMALL,MODE_MEDIUM,MODE_LARGE),这个是设计弹出dialog的大小
注意(优点):使用QuickContactBadge并不需要加入READ_CONTACTS权限。但是在无权限的情况下,如果联系人在通讯录里,则会直接进入查看联系人的界面,而不会有“拨打、查看、短信”三个选项。加入权限后则会出现
二、AsyncQueryHandler
AsyncQueryHandler:异步的查询操作帮助类,其实它同样可以处理增删改
1。AsyncQueryHandler的作用
查询其API便可知,它担供:
startInsert,startDelete,startUpdate,startQuery
这四个操作,并提供相对应的onXXXComplete方法,以供操作完数据库后进行其它的操作,这四个onXXXComplete方法都是空实现,以便我们只需要去实现我们关注的操作。
2。为什么要使用AsyncQueryHandler
当然你也可以使用ContentProvider去操作数据库。这在数据量很小的时候是没有问题的,但是如果数据量大了,可能导致UI线程发生ANR事件。当然你也可以写个Handler去做这些操作,只是你每次使用ContentProvider时都要再写个Handler,必然降低了效率。
因此API提供了一个操作数据库的通用方法。
3。如何使用AsyncQueryHandler
你只需要继承AsyncQueryHandler类,并提供onXXXComplete方法的实现(可以实现任何一个或多个,当然你也可以一个也不实现,如果你不关注操作数据库的結果),在你的实现中做一些对数据库操作完成的处理。
使用时直接调用startXXX方法即可。传入的通用参数如下:
int token,一个令牌,需要跟onXXXComplete方法传入的一致。(当然你也可以不一致,同样在数据库的操作结束后会调用对应的onXXXComplete方法 )
Object cookie,你想传给onXXXComplete方法使用的一个对象。(没有的话传递null即可。基本发现这个变量没太大作用)
Uri uri,操作数据的URi
4。AsyncQueryHandler还为我们做了什么
AsyncQueryHandler中使用了一个WeakReference<ContentResolver>对象,即 ContentResolver的弱引用 作用:当contentProvied发生变化时候同步更新仍可以通过使用 AsyncQueryHandler类来达到这一要求(暂时还没理解这个作用)
同时,在它执行操作数据库时,吃掉了所有的异常。见如下代码。
三、SparseArray的使用
SparseArray是 Android框架独有的类,在标准的JDK中不存在这个类。SparseArray实现了Cloneable接口,还可以调用clo
ne方法,它要比 HashMap 节省内存,某些情况下比HashMap性能更好,按照官方问答的解释,主要是因为SparseArray不需要
对key和value进行auto- boxing(将原始类型封装为对象类型,比如把int类型封装成Integer类型),结构比HashMap简单
(SparseArray内部主要使用 两个一维数组来保存数据,一个用来存key,一个用来存value)不需要额外的额外的数据结构(
主要是针对HashMap中的HashMapEntry 而言的)。
SparseArrays map integers to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
* than using a HashMap to map Integers to Objects, both because it avoids object for each mapping.
* auto-boxing keys and its data structure doesn't rely on an extra entry
acitivity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/contact_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#E1E6F6" > <ListView android:id="@+id/contact_list" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#7690A5" android:divider="#7690A5" android:fadingEdge="none" android:scrollbars="none" android:scrollingCache="false" android:visibility="visible" /> <com.zy.quilkycontact.AlphabeticBarandroid:id="@+id/fast_scroller" android:layout_width="22dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_gravity="top|right|center" android:layout_marginTop="0dip" android:background="@null" android:scaleType="centerInside" android:src="@drawable/dic_background" > </com.zy.quilkycontact.AlphabeticBar> <TextView android:id="@+id/fast_position" android:layout_width="70dip" android:layout_height="70dip" android:layout_centerInParent="true" android:layout_gravity="center_horizontal|top" android:layout_margin="34dip" android:background="@drawable/flag" android:gravity="center" android:padding="2dip" android:textColor="#404040" android:textSize="48dip" android:visibility="invisible" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <!-- 首字母 --> <TextView android:id="@+id/alpha" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#7690A5" android:paddingLeft="10dip" android:textColor="#FFFFFF" android:visibility="gone" /> <!-- 联系人信息 --> <QuickContactBadge android:id="@+id/contact" android:layout_width="75dip" android:layout_height="75dip" android:layout_alignParentLeft="true" android:layout_below="@+id/alpha" android:layout_marginBottom="3dip" android:layout_marginTop="3dip" android:src="@drawable/login_icon_member" style="?android:attr/quickContactBadgeStyleWindowSmall" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/contact" android:singleLine="true" android:layout_marginLeft="50dp" android:textAppearance="?android:textAppearanceLarge" android:textColor="#FFFFFF" /> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_toRightOf="@+id/contact" android:singleLine="true" android:layout_marginLeft="50dp" android:textAppearance="?android:textAppearanceSmall" android:textColor="#FFFFFF" /> </RelativeLayout>
package com.zy.quilkycontact; public class Contact {private int contactId; //id private String desplayName;//姓名 private String phoneNum; // 电话号码 private String sortKey; // 排序用的 private Long photoId; // 图片id private String lookUpKey; private int selected = 0; private String formattedNumber; private String pinyin; // 姓名拼音 private String email; public int getContactId() {return contactId; }public void setContactId(int contactId) {this.contactId = contactId; }public String getDesplayName() {return desplayName; }public void setDesplayName(String desplayName) {this.desplayName = desplayName; }public String getPhoneNum() {return phoneNum; }public void setPhoneNum(String phoneNum) {this.phoneNum = phoneNum; }public String getSortKey() {return sortKey; }public void setSortKey(String sortKey) {this.sortKey = sortKey; }public Long getPhotoId() {return photoId; }public void setPhotoId(Long photoId) {this.photoId = photoId; }public String getLookUpKey() {return lookUpKey; }public void setLookUpKey(String lookUpKey) {this.lookUpKey = lookUpKey; }public int getSelected() {return selected; }public void setSelected(int selected) {this.selected = selected; }public String getFormattedNumber() {return formattedNumber; }public void setFormattedNumber(String formattedNumber) {this.formattedNumber = formattedNumber; }public String getPinyin() {return pinyin; }public void setPinyin(String pinyin) {this.pinyin = pinyin; }public String getEmail() {return email; }public void setEmail(String email) {this.email = email; }
package com.zy.quilkycontact; import java.util.HashMap; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.ListView; import android.widget.TextView; /** * 字母索引条 * * */ public class AlphabeticBar extends ImageButton {private TextView mDialogText; // 中间显示字母的文本框 private Handler mHandler; // 处理UI的句柄 private ListView mList; // 列表 private float mHight; // 高度 // 字母列表索引 private String[] letters = new String[] { "#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; // 字母索引哈希表 private HashMap<String, Integer> alphaIndexer; Paint paint = new Paint(); boolean showBkg = false; int choose = -1; public AlphabeticBar(Context context) {this(context, null); }public AlphabeticBar(Context context, AttributeSet attrs) {this(context, attrs, 0); }public AlphabeticBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); }// 初始化 public void init(Activity ctx) {mDialogText = (TextView) ctx.findViewById(R.id.fast_position); mDialogText.setVisibility(View.INVISIBLE); mHandler = new Handler(); }// 设置需要索引的列表 public void setListView(ListView mList) {this.mList = mList; }// 设置字母索引哈希表 public void setAlphaIndexer(HashMap<String, Integer> alphaIndexer) {this.alphaIndexer = alphaIndexer; }// 设置字母索引条的高度 public void setHight(float mHight) {this.mHight = mHight; }@Overridepublic boolean onTouchEvent(MotionEvent event) {int act = event.getAction(); float y = event.getY(); final int oldChoose = choose; // 计算手指位置,找到对应的段,让mList移动段开头的位置上 int selectIndex = (int) (y / (mHight / letters.length)); if (selectIndex > -1 && selectIndex < letters.length) { // 防止越界 String key = letters[selectIndex]; if (alphaIndexer.containsKey(key)) {int pos = alphaIndexer.get(key); if (mList.getHeaderViewsCount() > 0) { // 防止ListView有标题栏,本例中没有 this.mList.setSelectionFromTop(pos + mList.getHeaderViewsCount(), 0); } else {this.mList.setSelectionFromTop(pos, 0); }}}switch (act) {case MotionEvent.ACTION_DOWN: showBkg = true; if (oldChoose != selectIndex) {if (selectIndex > 0 && selectIndex < letters.length) {choose = selectIndex; invalidate(); }}break; case MotionEvent.ACTION_MOVE: if (oldChoose != selectIndex) {if (selectIndex > 0 && selectIndex < letters.length) {choose = selectIndex; invalidate(); }}break; case MotionEvent.ACTION_UP: showBkg = false;// 不显示 choose = -1; break; default: break; }return super.onTouchEvent(event); }@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas); int height = getHeight(); int width = getWidth(); int sigleHeight = height / letters.length; // 单个字母占的高度 for (int i = 0; i < letters.length; i++) {paint.setColor(Color.WHITE); paint.setTextSize(20); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); if (i == choose) {paint.setColor(Color.parseColor("#00BFFF")); // 滑动时按下字母颜色 paint.setFakeBoldText(true); //选中后先显示选中的字目 mHandler.post(new Runnable() {@Overridepublic void run() {if (mDialogText != null) {mDialogText.setVisibility(VISIBLE); mDialogText.setText(letters[choose]);// 设置选中的滑动字母 }}}); //o.3秒后隐藏 mHandler.postDelayed(new Runnable() {@Overridepublic void run() {mDialogText.setVisibility(INVISIBLE); }}, 300); } // 绘画的位置 float xPos = width / 2 - paint.measureText(letters[i]) / 2; float yPos = sigleHeight * i + sigleHeight; canvas.drawText(letters[i], xPos, yPos, paint); paint.reset(); }}}
package com.zy.quilkycontact; import java.util.HashMap; import java.util.Map; import android.annotation.SuppressLint; import android.app.Activity; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.util.SparseArray; import android.view.View; import android.view.Window; import android.widget.ListView; /** * 联系人列表 * * */ public class MainActivity extends Activity {private ContactListAdapter adapter; private ListView contactListView; private SparseArray<Contact> list; private AsyncQueryHandler asyncQueryHandler; // 异步查询数据库类对象 private AlphabeticBar alphabeticBar; // 快速索引条 private Map<Integer, Contact> contactIdMap = null; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); contactListView = (ListView) findViewById(R.id.contact_list); alphabeticBar = (AlphabeticBar) findViewById(R.id.fast_scroller); // 实例化 asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver()); initDatas(); }/** * 初始化数据库查询参数 */ private void initDatas() {Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 联系人Uri; // 查询的字段 String[] projection = { ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key", ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.PHOTO_ID, ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY }; // 按照sort_key升序查詢 asyncQueryHandler.startQuery(0, null, uri, projection, null, null, "sort_key COLLATE LOCALIZED asc"); }/** * 使用异步方式对DB数据库进行基本的增,删,改,查 * */ private class MyAsyncQueryHandler extends AsyncQueryHandler {public MyAsyncQueryHandler(ContentResolver cr) {super(cr); }@SuppressLint("UseSparseArrays")protected void onQueryComplete(int token, Object cookie, Cursor cursor) {if (cursor != null && cursor.getCount() > 0) {contactIdMap = new HashMap<Integer, Contact>(); list = new SparseArray<Contact>(); cursor.moveToFirst(); // 游标移动到第一项 for (int i = 0; i < cursor.getCount(); i++) {cursor.moveToPosition(i); String name = cursor.getString(1); String number = cursor.getString(2); String sortKey = cursor.getString(3);//首字母 int contactId = cursor.getInt(4); Long photoId = cursor.getLong(5); String lookUpKey = cursor.getString(6); String email = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); if (contactIdMap.containsKey(contactId)) { // 无操作 } else { // 创建联系人对象 Contact contact = new Contact(); contact.setDesplayName(name); contact.setPhoneNum(number); contact.setSortKey(sortKey); contact.setPhotoId(photoId); contact.setLookUpKey(lookUpKey); contact.setEmail(email); list.put(i, contact); contactIdMap.put(contactId, contact); }}if (list.size() > 0) {setAdapter(list); }}super.onQueryComplete(token, cookie, cursor); }}private void setAdapter(SparseArray<Contact> list) {adapter = new ContactListAdapter(this, list, alphabeticBar); contactListView.setAdapter(adapter); alphabeticBar.init(MainActivity.this); alphabeticBar.setListView(contactListView); alphabeticBar.setHight(alphabeticBar.getHeight()); alphabeticBar.setVisibility(View.VISIBLE); } }
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- 写联系人权限 -->
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<!-- 拨号权限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- 读短信权限 -->
<uses-permission android:name="android.permission.READ_SMS" />
这篇关于安卓用QuickContactBadge和AsyncQueryHandler实现联系人列表的完美实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!