在公司开发这么久了,发现好多的控件没有用过,然后发现了一些新的知识感觉还是很不错的,今天在这里我就来用一下QuickContactBadge的控件和AsyncQueryHandler,说到底QuickContactBadge这个控件我也是偶然发现的,然后乘着现在公司的工作不忙,然后也准备换工作温习一下知识点罢了。
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是 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
</pre><span style="font-size:14px;">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 {<span style="white-space:pre"> </span>private TextView mDialogText; // 中间显示字母的文本框<span style="white-space:pre"> </span>private Handler mHandler; // 处理UI的句柄<span style="white-space:pre"> </span>private ListView mList; // 列表<span style="white-space:pre"> </span>private float mHight; // 高度<span style="white-space:pre"> </span>// 字母列表索引<span style="white-space:pre"> </span>private String[] letters = new String[] { "#", "A", "B", "C", "D", "E",<span style="white-space:pre"> </span>"F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",<span style="white-space:pre"> </span>"S", "T", "U", "V", "W", "X", "Y", "Z" };<span style="white-space:pre"> </span>// 字母索引哈希表<span style="white-space:pre"> </span>private HashMap<String, Integer> alphaIndexer;<span style="white-space:pre"> </span>Paint paint = new Paint();<span style="white-space:pre"> </span>boolean showBkg = false;<span style="white-space:pre"> </span>int choose = -1;<span style="white-space:pre"> </span>public AlphabeticBar(Context context) {<span style="white-space:pre"> </span>this(context, null);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>public AlphabeticBar(Context context, AttributeSet attrs) {<span style="white-space:pre"> </span>this(context, attrs, 0);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>public AlphabeticBar(Context context, AttributeSet attrs, int defStyle) {<span style="white-space:pre"> </span>super(context, attrs, defStyle);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 初始化<span style="white-space:pre"> </span>public void init(Activity ctx) {<span style="white-space:pre"> </span>mDialogText = (TextView) ctx.findViewById(R.id.fast_position);<span style="white-space:pre"> </span>mDialogText.setVisibility(View.INVISIBLE);<span style="white-space:pre"> </span>mHandler = new Handler();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 设置需要索引的列表<span style="white-space:pre"> </span>public void setListView(ListView mList) {<span style="white-space:pre"> </span>this.mList = mList;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 设置字母索引哈希表<span style="white-space:pre"> </span>public void setAlphaIndexer(HashMap<String, Integer> alphaIndexer) {<span style="white-space:pre"> </span>this.alphaIndexer = alphaIndexer;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 设置字母索引条的高度<span style="white-space:pre"> </span>public void setHight(float mHight) {<span style="white-space:pre"> </span>this.mHight = mHight;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public boolean onTouchEvent(MotionEvent event) {<span style="white-space:pre"> </span>int act = event.getAction();<span style="white-space:pre"> </span>float y = event.getY();<span style="white-space:pre"> </span>final int oldChoose = choose;<span style="white-space:pre"> </span>// 计算手指位置,找到对应的段,让mList移动段开头的位置上<span style="white-space:pre"> </span>int selectIndex = (int) (y / (mHight / letters.length));<span style="white-space:pre"> </span>if (selectIndex > -1 && selectIndex < letters.length) { // 防止越界<span style="white-space:pre"> </span>String key = letters[selectIndex];<span style="white-space:pre"> </span>if (alphaIndexer.containsKey(key)) {<span style="white-space:pre"> </span>int pos = alphaIndexer.get(key);<span style="white-space:pre"> </span>if (mList.getHeaderViewsCount() > 0) { // 防止ListView有标题栏,本例中没有<span style="white-space:pre"> </span>this.mList.setSelectionFromTop(<span style="white-space:pre"> </span>pos + mList.getHeaderViewsCount(), 0);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>this.mList.setSelectionFromTop(pos, 0);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>switch (act) {<span style="white-space:pre"> </span>case MotionEvent.ACTION_DOWN:<span style="white-space:pre"> </span>showBkg = true;<span style="white-space:pre"> </span>if (oldChoose != selectIndex) {<span style="white-space:pre"> </span>if (selectIndex > 0 && selectIndex < letters.length) {<span style="white-space:pre"> </span>choose = selectIndex;<span style="white-space:pre"> </span>invalidate();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span><span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>case MotionEvent.ACTION_MOVE:<span style="white-space:pre"> </span>if (oldChoose != selectIndex) {<span style="white-space:pre"> </span>if (selectIndex > 0 && selectIndex < letters.length) {<span style="white-space:pre"> </span>choose = selectIndex;<span style="white-space:pre"> </span>invalidate();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>case MotionEvent.ACTION_UP:<span style="white-space:pre"> </span>showBkg = false;// 不显示<span style="white-space:pre"> </span>choose = -1;<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>default:<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return super.onTouchEvent(event);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>protected void onDraw(Canvas canvas) {<span style="white-space:pre"> </span>super.onDraw(canvas);<span style="white-space:pre"> </span>int height = getHeight();<span style="white-space:pre"> </span>int width = getWidth();<span style="white-space:pre"> </span>int sigleHeight = height / letters.length; // 单个字母占的高度<span style="white-space:pre"> </span>for (int i = 0; i < letters.length; i++) {<span style="white-space:pre"> </span>paint.setColor(Color.WHITE);<span style="white-space:pre"> </span>paint.setTextSize(20);<span style="white-space:pre"> </span>paint.setTypeface(Typeface.DEFAULT_BOLD);<span style="white-space:pre"> </span>paint.setAntiAlias(true);<span style="white-space:pre"> </span>if (i == choose) {<span style="white-space:pre"> </span>paint.setColor(Color.parseColor("#00BFFF")); // 滑动时按下字母颜色<span style="white-space:pre"> </span>paint.setFakeBoldText(true);<span style="white-space:pre"> </span>//选中后先显示选中的字目<span style="white-space:pre"> </span>mHandler.post(new Runnable() {<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public void run() {<span style="white-space:pre"> </span>if (mDialogText != null) {<span style="white-space:pre"> </span>mDialogText.setVisibility(VISIBLE);<span style="white-space:pre"> </span>mDialogText.setText(letters[choose]);// 设置选中的滑动字母<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>});<span style="white-space:pre"> </span>//o.3秒后隐藏<span style="white-space:pre"> </span>mHandler.postDelayed(new Runnable() {<span style="white-space:pre"> </span><span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public void run() {<span style="white-space:pre"> </span>mDialogText.setVisibility(INVISIBLE);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}, 300);<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 绘画的位置<span style="white-space:pre"> </span>float xPos = width / 2 - paint.measureText(letters[i]) / 2;<span style="white-space:pre"> </span>float yPos = sigleHeight * i + sigleHeight;<span style="white-space:pre"> </span>canvas.drawText(letters[i], xPos, yPos, paint);<span style="white-space:pre"> </span>paint.reset();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}}</span><div style="text-align: justify; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;"><span style="font-size:14px;"><span style="line-height:13.75px; white-space:pre"></span></span></div><span style="font-size:14px;"><span style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; line-height: 13.75px; white-space: pre !important;"></span></span><div style="text-align:justify"><span style="font-size:14px;">3.接下来我们就写联系人的适配器ContactListAdapter.java</span></div><div style="text-align:justify"><span style="font-size:14px;">package com.zy.quilkycontact;import java.io.InputStream;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Set;import java.util.regex.Pattern;import android.content.ContentUris;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.provider.ContactsContract;import android.provider.ContactsContract.Contacts;import android.provider.ContactsContract.QuickContact;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.QuickContactBadge;import android.widget.TextView;public class ContactListAdapter extends BaseAdapter {<span style="white-space:pre"> </span>private LayoutInflater inflater;<span style="white-space:pre"> </span>private SparseArray<Contact> list;<span style="white-space:pre"> </span>private HashMap<String, Integer> alphaIndexer; // 字母索引<span style="white-space:pre"> </span>private String[] sections; // 存储每个章节<span style="white-space:pre"> </span>private Context ctx; // 上下文<span style="white-space:pre"> </span>public ContactListAdapter(Context context, SparseArray<Contact> list,<span style="white-space:pre"> </span>AlphabeticBar alpha) {<span style="white-space:pre"> </span>this.ctx = context;<span style="white-space:pre"> </span>this.inflater = LayoutInflater.from(context);<span style="white-space:pre"> </span>this.list = list;<span style="white-space:pre"> </span>this.alphaIndexer = new HashMap<String, Integer>();<span style="white-space:pre"> </span>this.sections = new String[list.size()]; int count=list.size();<span style="white-space:pre"> </span>for (int i = 0; i <count; i++) {<span style="white-space:pre"> </span>// 得到字母字符串的首字母<span style="white-space:pre"> </span>String name = getAlpha(list.get(i).getSortKey());<span style="white-space:pre"> </span>if (!alphaIndexer.containsKey(name)) {<span style="white-space:pre"> </span>alphaIndexer.put(name, i);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>Set<String> sectionLetters = alphaIndexer.keySet();//获取所有的key值<span style="white-space:pre"> </span>ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);<span style="white-space:pre"> </span>Collections.sort(sectionList); // 根据首字母进行排序<span style="white-space:pre"> </span>sections = new String[sectionList.size()];<span style="white-space:pre"> </span>sectionList.toArray(sections);//转化为数组<span style="white-space:pre"> </span>alpha.setAlphaIndexer(alphaIndexer);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public int getCount() {<span style="white-space:pre"> </span>return list.size();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public Object getItem(int position) {<span style="white-space:pre"> </span>return list.get(position);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public long getItemId(int position) {<span style="white-space:pre"> </span>return position;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>public void remove(int position) {<span style="white-space:pre"> </span>list.remove(position);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>@Override<span style="white-space:pre"> </span>public View getView(int position, View convertView, ViewGroup parent) {<span style="white-space:pre"> </span>ViewHolder holder;<span style="white-space:pre"> </span>if (convertView == null) {<span style="white-space:pre"> </span>convertView = inflater.inflate(R.layout.contact_list_item, parent,false);<span style="white-space:pre"> </span>holder = new ViewHolder();<span style="white-space:pre"> </span>holder.quickContactBadge = (QuickContactBadge) convertView<span style="white-space:pre"> </span>.findViewById(R.id.contact);<span style="white-space:pre"> </span>holder.alpha = (TextView) convertView.findViewById(R.id.alpha);<span style="white-space:pre"> </span>holder.name = (TextView) convertView.findViewById(R.id.name);<span style="white-space:pre"> </span>holder.number = (TextView) convertView.findViewById(R.id.number);<span style="white-space:pre"> </span>convertView.setTag(holder);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>holder = (ViewHolder) convertView.getTag();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>Contact contact = list.get(position);<span style="white-space:pre"> </span>String name = contact.getDesplayName();<span style="white-space:pre"> </span>String number = contact.getPhoneNum();<span style="white-space:pre"> </span>holder.name.setText(name);<span style="white-space:pre"> </span>holder.number.setText(number);<span style="white-space:pre"> </span>holder.quickContactBadge.assignContactUri(Contacts.getLookupUri(<span style="white-space:pre"> </span>contact.getContactId(), contact.getLookUpKey()));<span style="white-space:pre"> </span>//holder.quickContactBadge.assignContactFromEmail(contact.getEmail(),false);//关联emali<span style="white-space:pre"> </span>holder.quickContactBadge.setMode(ContactsContract.QuickContact.MODE_SMALL);<span style="white-space:pre"> </span><span style="white-space:pre"> </span>if (0 == contact.getPhotoId()) {<span style="white-space:pre"> </span>holder.quickContactBadge.setImageResource(R.drawable.login_icon_member);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>Uri uri = ContentUris.withAppendedId(<span style="white-space:pre"> </span>ContactsContract.Contacts.CONTENT_URI,<span style="white-space:pre"> </span>contact.getContactId());<span style="white-space:pre"> </span>InputStream input = ContactsContract.Contacts<span style="white-space:pre"> </span>.openContactPhotoInputStream(ctx.getContentResolver(), uri);<span style="white-space:pre"> </span>Bitmap contactPhoto = BitmapFactory.decodeStream(input);<span style="white-space:pre"> </span>holder.quickContactBadge.setImageBitmap(contactPhoto);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 当前显示的首字母<span style="white-space:pre"> </span>String currentStr = getAlpha(contact.getSortKey());<span style="white-space:pre"> </span>// 前面的字母<span style="white-space:pre"> </span>String previewStr = (position - 1) >= 0 ? getAlpha(list.get(<span style="white-space:pre"> </span>position - 1).getSortKey()) : " ";<span style="white-space:pre"> </span>if (!previewStr.equals(currentStr)) {//如果当前显示的首字母和以前的首字母不同<span style="white-space:pre"> </span>holder.alpha.setVisibility(View.VISIBLE);//显示<span style="white-space:pre"> </span>holder.alpha.setText(currentStr);<span style="white-space:pre"> </span>} else {//相同时顶部栏不显示<span style="white-space:pre"> </span>holder.alpha.setVisibility(View.GONE);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return convertView;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>private static class ViewHolder {<span style="white-space:pre"> </span>QuickContactBadge quickContactBadge;<span style="white-space:pre"> </span>TextView alpha;<span style="white-space:pre"> </span>TextView name;<span style="white-space:pre"> </span>TextView number;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>/**<span style="white-space:pre"> </span> * 获取首字母<span style="white-space:pre"> </span> * <span style="white-space:pre"> </span> * @param str<span style="white-space:pre"> </span> * @return<span style="white-space:pre"> </span> */<span style="white-space:pre"> </span>private String getAlpha(String str) {<span style="white-space:pre"> </span>if (str == null) {//字母不存在返回为#号<span style="white-space:pre"> </span>return "#";<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>if (str.trim().length() == 0) {<span style="white-space:pre"> </span>return "#";<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>char c = str.trim().substring(0, 1).charAt(0);//获取首字母<span style="white-space:pre"> </span>// 正则表达式匹配(从a到z的字母)<span style="white-space:pre"> </span>Pattern pattern = Pattern.compile("^[A-Za-z]+$");<span style="white-space:pre"> </span>if (pattern.matcher(c + "").matches()) {//如果首字母是a-z里面的任一字母<span style="white-space:pre"> </span>return (c + "").toUpperCase(); // 将小写字母转换为大写<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>return "#";<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}}</span></div></div><div class="line number1 index0 alt2" style="padding:0px 1em!important; margin:0px!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important"><div style="text-align:justify; white-space:pre!important"><span style="font-size:14px;">4.最后我们就可以书写mainActivity.java的代码:</span></div></div><div class="line number1 index0 alt2" style="padding:0px 1em!important; margin:0px!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important"><pre name="code" class="html" style="text-align: justify; white-space: pre !important;">package com.zy.quilkycontact;