转自:

http://blog.csdn.net/wwj_748/article/details/19965913

 

Android通讯录管理(获取联系人、通话记录、短信消息)
 
2014年2月26日 通讯录开发研究学习
 
前言:前阵子主要是记录了如何对联系人的一些操作,比如搜索,全选、反选和删除等在实际开发中可能需要实现的功能,本篇博客是小巫从一个别人开源的一个项目抽取出来的部分内容,把它给简化出来,可以让需要的朋友清楚知道如何对Android数据库操作,异步查询数据库获取我们需要的内容。由于内容比较多,我将分三篇博客来讲述获取联系人、通话记录、短信消息的实现。
 
 
也许你根本就没耐心看,源码在这里 http://download.csdn.net/detail/wwj_748/6962865,骚年去下吧。
 
 
 


上面的是获取联系人的界面效果,实现分组显示联系人,快速索引条查找联系人,下面是实现:

从权限开始:
[html]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. <!-- 读联系人权限 -->  
  2. <uses-permission android:name="android.permission.READ_CONTACTS" />  
  3. <!-- 写联系人权限 -->  
  4. <uses-permission android:name="android.permission.WRITE_CONTACTS" />  
  5. <!-- 拨号权限 -->  
  6. <uses-permission android:name="android.permission.CALL_PHONE" />  
  7. <!-- 读短信权限 -->  
  8. <uses-permission android:name="android.permission.READ_SMS" />  



界面布局:
/Contact_Demo/res/layout/contact_list_view.xml
[html]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/contact_list_view"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:background="#000000" >  
  7.   
  8.     <com.suntek.contact.view.SlidingLinearLayout  
  9.         android:id="@+id/slidingview"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent"  
  12.         android:layout_alignParentTop="true" >  
  13.   
  14.         <ListView  
  15.             android:id="@+id/contact_list"  
  16.             android:layout_width="match_parent"  
  17.             android:layout_height="match_parent"  
  18.             android:cacheColorHint="#000000"  
  19.             android:divider="#00000000"  
  20.             android:fadingEdge="none"  
  21.             android:scrollbars="none"  
  22.             android:scrollingCache="false"  
  23.             android:visibility="visible" />  
  24.     </com.suntek.contact.view.SlidingLinearLayout>  
  25.   
  26.     <com.suntek.contact.view.QuickAlphabeticBar  
  27.         android:id="@+id/fast_scroller"  
  28.         android:layout_width="22dp"  
  29.         android:layout_height="match_parent"  
  30.         android:layout_alignParentRight="true"  
  31.         android:layout_gravity="top|right|center"  
  32.         android:layout_marginTop="0dip"  
  33.         android:background="@null"  
  34.         android:scaleType="centerInside"  
  35.         android:src="@drawable/dic_background" >  
  36.     </com.suntek.contact.view.QuickAlphabeticBar>  
  37.   
  38.     <TextView  
  39.         android:id="@+id/fast_position"  
  40.         android:layout_width="70dip"  
  41.         android:layout_height="70dip"  
  42.         android:layout_centerInParent="true"  
  43.         android:layout_gravity="center_horizontal|top"  
  44.         android:layout_margin="34dip"  
  45.         android:background="@drawable/sort_icon_bg_click"  
  46.         android:gravity="center"  
  47.         android:padding="2dip"  
  48.         android:textColor="#404040"  
  49.         android:textSize="48dip"  
  50.         android:visibility="invisible" />  
  51.   
  52. </RelativeLayout>  

/Contact_Demo/res/layout/contact_list_item.xml
[html]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content" >  
  5.   
  6.     <!-- 首字母 -->  
  7.   
  8.     <TextView  
  9.         android:id="@+id/alpha"  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:background="#333333"  
  13.         android:paddingLeft="10dip"  
  14.         android:textColor="#FFFFFF"  
  15.         android:visibility="gone" />  
  16.   
  17.     <!-- 联系人信息 -->  
  18.   
  19.     <QuickContactBadge  
  20.         android:id="@+id/qcb"  
  21.         android:layout_width="75dip"  
  22.         android:layout_height="75dip"  
  23.         android:layout_alignParentLeft="true"  
  24.         android:layout_below="@+id/alpha"  
  25.         android:layout_marginBottom="3dip"  
  26.         android:layout_marginTop="3dip"  
  27.         android:src="@drawable/touxiang" />  
  28.   
  29.     <TextView  
  30.         android:id="@+id/name"  
  31.         android:layout_width="wrap_content"  
  32.         android:layout_height="wrap_content"  
  33.         android:layout_centerVertical="true"  
  34.         android:layout_marginLeft="5.0dip"  
  35.         android:layout_toRightOf="@+id/qcb"  
  36.         android:singleLine="true"  
  37.         android:textAppearance="?android:textAppearanceLarge"  
  38.         android:textColor="#FFFFFF" />  
  39.   
  40.     <TextView  
  41.         android:id="@+id/number"  
  42.         android:layout_width="wrap_content"  
  43.         android:layout_height="wrap_content"  
  44.         android:layout_alignParentBottom="true"  
  45.         android:layout_marginLeft="5.0dip"  
  46.         android:layout_toRightOf="@+id/qcb"  
  47.         android:singleLine="true"  
  48.         android:textAppearance="?android:textAppearanceSmall"  
  49.         android:textColor="#FFFFFF" />  
  50.   
  51. </RelativeLayout>  


代码实现:

1. 先定义一个实体类,用来保存联系人信息
/Contact_Demo/src/com/suntek/contact/model/ContactBean.java
[java]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. package com.suntek.contact.model;  
  2.   
  3. public class ContactBean {  
  4.   
  5.     private int contactId; //id  
  6.     private String desplayName;//姓名  
  7.     private String phoneNum; // 电话号码  
  8.     private String sortKey; // 排序用的  
  9.     private Long photoId; // 图片id  
  10.     private String lookUpKey;   
  11.     private int selected = 0;  
  12.     private String formattedNumber;  
  13.     private String pinyin; // 姓名拼音  
  14.   
  15.     public int getContactId() {  
  16.         return contactId;  
  17.     }  
  18.   
  19.     public void setContactId(int contactId) {  
  20.         this.contactId = contactId;  
  21.     }  
  22.   
  23.     public String getDesplayName() {  
  24.         return desplayName;  
  25.     }  
  26.   
  27.     public void setDesplayName(String desplayName) {  
  28.         this.desplayName = desplayName;  
  29.     }  
  30.   
  31.     public String getPhoneNum() {  
  32.         return phoneNum;  
  33.     }  
  34.   
  35.     public void setPhoneNum(String phoneNum) {  
  36.         this.phoneNum = phoneNum;  
  37.     }  
  38.   
  39.     public String getSortKey() {  
  40.         return sortKey;  
  41.     }  
  42.   
  43.     public void setSortKey(String sortKey) {  
  44.         this.sortKey = sortKey;  
  45.     }  
  46.   
  47.     public Long getPhotoId() {  
  48.         return photoId;  
  49.     }  
  50.   
  51.     public void setPhotoId(Long photoId) {  
  52.         this.photoId = photoId;  
  53.     }  
  54.   
  55.     public String getLookUpKey() {  
  56.         return lookUpKey;  
  57.     }  
  58.   
  59.     public void setLookUpKey(String lookUpKey) {  
  60.         this.lookUpKey = lookUpKey;  
  61.     }  
  62.   
  63.     public int getSelected() {  
  64.         return selected;  
  65.     }  
  66.   
  67.     public void setSelected(int selected) {  
  68.         this.selected = selected;  
  69.     }  
  70.   
  71.     public String getFormattedNumber() {  
  72.         return formattedNumber;  
  73.     }  
  74.   
  75.     public void setFormattedNumber(String formattedNumber) {  
  76.         this.formattedNumber = formattedNumber;  
  77.     }  
  78.   
  79.     public String getPinyin() {  
  80.         return pinyin;  
  81.     }  
  82.   
  83.     public void setPinyin(String pinyin) {  
  84.         this.pinyin = pinyin;  
  85.     }  
  86.   
  87. }  


适配器:
/Contact_Demo/src/com/suntek/contact/adapter/ContactListAdapter.java
[java]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. package com.suntek.contact.adapter;  
  2.   
  3. import java.io.InputStream;  
  4. import java.util.ArrayList;  
  5. import java.util.Collections;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Set;  
  9. import java.util.regex.Pattern;  
  10.   
  11. import android.content.ContentUris;  
  12. import android.content.Context;  
  13. import android.graphics.Bitmap;  
  14. import android.graphics.BitmapFactory;  
  15. import android.net.Uri;  
  16. import android.provider.ContactsContract;  
  17. import android.provider.ContactsContract.Contacts;  
  18. import android.view.LayoutInflater;  
  19. import android.view.View;  
  20. import android.view.ViewGroup;  
  21. import android.widget.BaseAdapter;  
  22. import android.widget.QuickContactBadge;  
  23. import android.widget.TextView;  
  24.   
  25. import com.suntek.contact.R;  
  26. import com.suntek.contact.model.ContactBean;  
  27. import com.suntek.contact.view.QuickAlphabeticBar;  
  28.   
  29. public class ContactListAdapter extends BaseAdapter {  
  30.     private LayoutInflater inflater;  
  31.     private List<ContactBean> list;  
  32.     private HashMap<String, Integer> alphaIndexer; // 字母索引  
  33.     private String[] sections; // 存储每个章节  
  34.     private Context ctx; // 上下文  
  35.   
  36.     public ContactListAdapter(Context context, List<ContactBean> list,  
  37.             QuickAlphabeticBar alpha) {  
  38.         this.ctx = context;  
  39.         this.inflater = LayoutInflater.from(context);  
  40.         this.list = list;  
  41.         this.alphaIndexer = new HashMap<String, Integer>();  
  42.         this.sections = new String[list.size()];  
  43.   
  44.         for (int i = 0; i < list.size(); i++) {  
  45.             // 得到字母  
  46.             String name = getAlpha(list.get(i).getSortKey());  
  47.             if (!alphaIndexer.containsKey(name)) {  
  48.                 alphaIndexer.put(name, i);  
  49.             }  
  50.         }  
  51.   
  52.         Set<String> sectionLetters = alphaIndexer.keySet();  
  53.         ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);  
  54.         Collections.sort(sectionList); // 根据首字母进行排序  
  55.         sections = new String[sectionList.size()];  
  56.         sectionList.toArray(sections);  
  57.   
  58.         alpha.setAlphaIndexer(alphaIndexer);  
  59.   
  60.     }  
  61.   
  62.     @Override  
  63.     public int getCount() {  
  64.         return list.size();  
  65.     }  
  66.   
  67.     @Override  
  68.     public Object getItem(int position) {  
  69.         return list.get(position);  
  70.     }  
  71.   
  72.     @Override  
  73.     public long getItemId(int position) {  
  74.         return position;  
  75.     }  
  76.   
  77.     public void remove(int position) {  
  78.         list.remove(position);  
  79.     }  
  80.   
  81.     @Override  
  82.     public View getView(int position, View convertView, ViewGroup parent) {  
  83.         ViewHolder holder;  
  84.         if (convertView == null) {  
  85.             convertView = inflater.inflate(R.layout.contact_list_item, null);  
  86.             holder = new ViewHolder();  
  87.             holder.quickContactBadge = (QuickContactBadge) convertView  
  88.                     .findViewById(R.id.qcb);  
  89.             holder.alpha = (TextView) convertView.findViewById(R.id.alpha);  
  90.             holder.name = (TextView) convertView.findViewById(R.id.name);  
  91.             holder.number = (TextView) convertView.findViewById(R.id.number);  
  92.             convertView.setTag(holder);  
  93.         } else {  
  94.             holder = (ViewHolder) convertView.getTag();  
  95.         }  
  96.   
  97.         ContactBean contact = list.get(position);  
  98.         String name = contact.getDesplayName();  
  99.         String number = contact.getPhoneNum();  
  100.         holder.name.setText(name);  
  101.         holder.number.setText(number);  
  102.         holder.quickContactBadge.assignContactUri(Contacts.getLookupUri(  
  103.                 contact.getContactId(), contact.getLookUpKey()));  
  104.         if (0 == contact.getPhotoId()) {  
  105.             holder.quickContactBadge.setImageResource(R.drawable.touxiang);  
  106.         } else {  
  107.             Uri uri = ContentUris.withAppendedId(  
  108.                     ContactsContract.Contacts.CONTENT_URI,  
  109.                     contact.getContactId());  
  110.             InputStream input = ContactsContract.Contacts  
  111.                     .openContactPhotoInputStream(ctx.getContentResolver(), uri);  
  112.             Bitmap contactPhoto = BitmapFactory.decodeStream(input);  
  113.             holder.quickContactBadge.setImageBitmap(contactPhoto);  
  114.         }  
  115.         // 当前字母  
  116.         String currentStr = getAlpha(contact.getSortKey());  
  117.         // 前面的字母  
  118.         String previewStr = (position - 1) >= 0 ? getAlpha(list.get(  
  119.                 position - 1).getSortKey()) : " ";  
  120.   
  121.         if (!previewStr.equals(currentStr)) {  
  122.             holder.alpha.setVisibility(View.VISIBLE);  
  123.             holder.alpha.setText(currentStr);  
  124.         } else {  
  125.             holder.alpha.setVisibility(View.GONE);  
  126.         }  
  127.         return convertView;  
  128.     }  
  129.   
  130.     private static class ViewHolder {  
  131.         QuickContactBadge quickContactBadge;  
  132.         TextView alpha;  
  133.         TextView name;  
  134.         TextView number;  
  135.     }  
  136.   
  137.     /** 
  138.      * 获取首字母 
  139.      *  
  140.      * @param str 
  141.      * @return 
  142.      */  
  143.     private String getAlpha(String str) {  
  144.         if (str == null) {  
  145.             return "#";  
  146.         }  
  147.         if (str.trim().length() == 0) {  
  148.             return "#";  
  149.         }  
  150.         char c = str.trim().substring(0, 1).charAt(0);  
  151.         // 正则表达式匹配  
  152.         Pattern pattern = Pattern.compile("^[A-Za-z]+$");  
  153.         if (pattern.matcher(c + "").matches()) {  
  154.             return (c + "").toUpperCase(); // 将小写字母转换为大写  
  155.         } else {  
  156.             return "#";  
  157.         }  
  158.     }  
  159. }  


/Contact_Demo/src/com/suntek/contact/ContactListActivity.java
[java]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. package com.suntek.contact;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import android.app.Activity;  
  9. import android.content.AsyncQueryHandler;  
  10. import android.content.ContentResolver;  
  11. import android.database.Cursor;  
  12. import android.net.Uri;  
  13. import android.os.Bundle;  
  14. import android.provider.ContactsContract;  
  15. import android.view.View;  
  16. import android.widget.ListView;  
  17.   
  18. import com.suntek.contact.adapter.ContactListAdapter;  
  19. import com.suntek.contact.model.ContactBean;  
  20. import com.suntek.contact.view.QuickAlphabeticBar;  
  21.   
  22. /** 
  23.  * 联系人列表 
  24.  *  
  25.  * @author Administrator 
  26.  *  
  27.  */  
  28. public class ContactListActivity extends Activity {  
  29.   
  30.     private ContactListAdapter adapter;  
  31.     private ListView contactList;  
  32.     private List<ContactBean> list;  
  33.     private AsyncQueryHandler asyncQueryHandler; // 异步查询数据库类对象  
  34.     private QuickAlphabeticBar alphabeticBar; // 快速索引条  
  35.   
  36.     private Map<Integer, ContactBean> contactIdMap = null;  
  37.   
  38.     @Override  
  39.     protected void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.contact_list_view);  
  42.         contactList = (ListView) findViewById(R.id.contact_list);  
  43.         alphabeticBar = (QuickAlphabeticBar) findViewById(R.id.fast_scroller);  
  44.   
  45.         // 实例化  
  46.         asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver());  
  47.         init();  
  48.   
  49.     }  
  50.   
  51.     /** 
  52.      * 初始化数据库查询参数 
  53.      */  
  54.     private void init() {  
  55.         Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 联系人Uri;  
  56.         // 查询的字段  
  57.         String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,  
  58.                 ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,  
  59.                 ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key",  
  60.                 ContactsContract.CommonDataKinds.Phone.CONTACT_ID,  
  61.                 ContactsContract.CommonDataKinds.Phone.PHOTO_ID,  
  62.                 ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY };  
  63.         // 按照sort_key升序查詢  
  64.         asyncQueryHandler.startQuery(0, null, uri, projection, null, null,  
  65.                 "sort_key COLLATE LOCALIZED asc");  
  66.   
  67.     }  
  68.   
  69.     /** 
  70.      *  
  71.      * @author Administrator 
  72.      *  
  73.      */  
  74.     private class MyAsyncQueryHandler extends AsyncQueryHandler {  
  75.   
  76.         public MyAsyncQueryHandler(ContentResolver cr) {  
  77.             super(cr);  
  78.         }  
  79.   
  80.         @Override  
  81.         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {  
  82.             if (cursor != null && cursor.getCount() > 0) {  
  83.                 contactIdMap = new HashMap<Integer, ContactBean>();  
  84.                 list = new ArrayList<ContactBean>();  
  85.                 cursor.moveToFirst(); // 游标移动到第一项  
  86.                 for (int i = 0; i < cursor.getCount(); i++) {  
  87.                     cursor.moveToPosition(i);  
  88.                     String name = cursor.getString(1);  
  89.                     String number = cursor.getString(2);  
  90.                     String sortKey = cursor.getString(3);  
  91.                     int contactId = cursor.getInt(4);  
  92.                     Long photoId = cursor.getLong(5);  
  93.                     String lookUpKey = cursor.getString(6);  
  94.   
  95.                     if (contactIdMap.containsKey(contactId)) {  
  96.                         // 无操作  
  97.                     } else {  
  98.                         // 创建联系人对象  
  99.                         ContactBean contact = new ContactBean();  
  100.                         contact.setDesplayName(name);  
  101.                         contact.setPhoneNum(number);  
  102.                         contact.setSortKey(sortKey);  
  103.                         contact.setPhotoId(photoId);  
  104.                         contact.setLookUpKey(lookUpKey);  
  105.                         list.add(contact);  
  106.   
  107.                         contactIdMap.put(contactId, contact);  
  108.                     }  
  109.                 }  
  110.                 if (list.size() > 0) {  
  111.                     setAdapter(list);  
  112.                 }  
  113.             }  
  114.   
  115.             super.onQueryComplete(token, cookie, cursor);  
  116.         }  
  117.   
  118.     }  
  119.   
  120.     private void setAdapter(List<ContactBean> list) {  
  121.         adapter = new ContactListAdapter(this, list, alphabeticBar);  
  122.         contactList.setAdapter(adapter);  
  123.         alphabeticBar.init(ContactListActivity.this);  
  124.         alphabeticBar.setListView(contactList);  
  125.         alphabeticBar.setHight(alphabeticBar.getHeight());  
  126.         alphabeticBar.setVisibility(View.VISIBLE);  
  127.     }  
  128. }  
自定义组件:

[java]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. package com.suntek.contact.view;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.view.MotionEvent;  
  6. import android.widget.LinearLayout;  
  7.   
  8. public class SlidingLinearLayout extends LinearLayout {  
  9.   
  10.     public SlidingLinearLayout(Context context, AttributeSet attrs) {  
  11.         super(context, attrs);  
  12.     }  
  13.   
  14.     @Override  
  15.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  16.         return super.onInterceptTouchEvent(ev);  
  17.     }  
  18.   
  19. }  


/Contact_Demo/src/com/suntek/contact/view/QuickAlphabeticBar.java
[java]  view plain copy 在CODE上查看代码片派生到我的代码片
 
  1. package com.suntek.contact.view;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.Context;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Paint;  
  10. import android.graphics.Typeface;  
  11. import android.os.Handler;  
  12. import android.util.AttributeSet;  
  13. import android.view.MotionEvent;  
  14. import android.view.View;  
  15. import android.widget.ImageButton;  
  16. import android.widget.ListView;  
  17. import android.widget.TextView;  
  18.   
  19. import com.suntek.contact.R;  
  20.   
  21. /** 
  22.  * 字母索引条 
  23.  *  
  24.  * @author Administrator 
  25.  *  
  26.  */  
  27. public class QuickAlphabeticBar extends ImageButton {  
  28.     private TextView mDialogText; // 中间显示字母的文本框  
  29.     private Handler mHandler; // 处理UI的句柄  
  30.     private ListView mList; // 列表  
  31.     private float mHight; // 高度  
  32.     // 字母列表索引  
  33.     private String[] letters = new String[] { "#", "A", "B", "C", "D", "E",  
  34.             "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",  
  35.             "S", "T", "U", "V", "W", "X", "Y", "Z" };  
  36.     // 字母索引哈希表  
  37.     private HashMap<String, Integer> alphaIndexer;  
  38.     Paint paint = new Paint();  
  39.     boolean showBkg = false;  
  40.     int choose = -1;  
  41.   
  42.     public QuickAlphabeticBar(Context context) {  
  43.         super(context);  
  44.     }  
  45.   
  46.     public QuickAlphabeticBar(Context context, AttributeSet attrs, int defStyle) {  
  47.         super(context, attrs, defStyle);  
  48.     }  
  49.   
  50.     public QuickAlphabeticBar(Context context, AttributeSet attrs) {  
  51.         super(context, attrs);  
  52.     }  
  53.   
  54.     // 初始化  
  55.     public void init(Activity ctx) {  
  56.         mDialogText = (TextView) ctx.findViewById(R.id.fast_position);  
  57.         mDialogText.setVisibility(View.INVISIBLE);  
  58.         mHandler = new Handler();  
  59.     }  
  60.   
  61.     // 设置需要索引的列表  
  62.     public void setListView(ListView mList) {  
  63.         this.mList = mList;  
  64.     }  
  65.   
  66.     // 设置字母索引哈希表  
  67.     public void setAlphaIndexer(HashMap<String, Integer> alphaIndexer) {  
  68.         this.alphaIndexer = alphaIndexer;  
  69.     }  
  70.   
  71.     // 设置字母索引条的高度  
  72.     public void setHight(float mHight) {  
  73.         this.mHight = mHight;  
  74.     }  
  75.   
  76.     @Override  
  77.     public boolean onTouchEvent(MotionEvent event) {  
  78.         int act = event.getAction();  
  79.         float y = event.getY();  
  80.         final int oldChoose = choose;  
  81.         // 计算手指位置,找到对应的段,让mList移动段开头的位置上  
  82.         int selectIndex = (int) (y / (mHight / letters.length));  
  83.   
  84.         if (selectIndex > -1 && selectIndex < letters.length) { // 防止越界  
  85.             String key = letters[selectIndex];  
  86.             if (alphaIndexer.containsKey(key)) {  
  87.                 int pos = alphaIndexer.get(key);  
  88.                 if (mList.getHeaderViewsCount() > 0) { // 防止ListView有标题栏,本例中没有  
  89.                     this.mList.setSelectionFromTop(  
  90.                             pos + mList.getHeaderViewsCount(), 0);  
  91.                 } else {  
  92.                     this.mList.setSelectionFromTop(pos, 0);  
  93.                 }  
  94.                 mDialogText.setText(letters[selectIndex]);  
  95.             }  
  96.         }  
  97.         switch (act) {  
  98.         case MotionEvent.ACTION_DOWN:  
  99.             showBkg = true;  
  100.             if (oldChoose != selectIndex) {  
  101.                 if (selectIndex > 0 && selectIndex < letters.length) {  
  102.                     choose = selectIndex;  
  103.                     invalidate();  
  104.                 }  
  105.             }  
  106.             if (mHandler != null) {  
  107.                 mHandler.post(new Runnable() {  
  108.   
  109.                     @Override  
  110.                     public void run() {  
  111.                         if (mDialogText != null  
  112.                                 && mDialogText.getVisibility() == View.INVISIBLE) {  
  113.                             mDialogText.setVisibility(VISIBLE);  
  114.                         }  
  115.                     }  
  116.                 });  
  117.             }  
  118.             break;  
  119.         case MotionEvent.ACTION_MOVE:  
  120.             if (oldChoose != selectIndex) {  
  121.                 if (selectIndex > 0 && selectIndex < letters.length) {  
  122.                     choose = selectIndex;  
  123.                     invalidate();  
  124.                 }  
  125.             }  
  126.             break;  
  127.         case MotionEvent.ACTION_UP:  
  128.             showBkg = false;  
  129.             choose = -1;  
  130.             if (mHandler != null) {  
  131.                 mHandler.post(new Runnable() {  
  132.   
  133.                     @Override  
  134.                     public void run() {  
  135.                         if (mDialogText != null  
  136.                                 && mDialogText.getVisibility() == View.VISIBLE) {  
  137.                             mDialogText.setVisibility(INVISIBLE);  
  138.                         }  
  139.                     }  
  140.                 });  
  141.             }  
  142.             break;  
  143.         default:  
  144.             break;  
  145.         }  
  146.         return super.onTouchEvent(event);  
  147.     }  
  148.   
  149.     @Override  
  150.     protected void onDraw(Canvas canvas) {  
  151.         super.onDraw(canvas);  
  152.         int height = getHeight();  
  153.         int width = getWidth();  
  154.         int sigleHeight = height / letters.length; // 单个字母占的高度  
  155.         for (int i = 0; i < letters.length; i++) {  
  156.             paint.setColor(Color.WHITE);  
  157.             paint.setTextSize(20);  
  158.             paint.setTypeface(Typeface.DEFAULT_BOLD);  
  159.             paint.setAntiAlias(true);  
  160.             if (i == choose) {   
  161.                 paint.setColor(Color.parseColor("#00BFFF")); // 滑动时按下字母颜色  
  162.                 paint.setFakeBoldText(true);  
  163.             }  
  164.             // 绘画的位置  
  165.             float xPos = width / 2 - paint.measureText(letters[i]) / 2;  
  166.             float yPos = sigleHeight * i + sigleHeight;  
  167.             canvas.drawText(letters[i], xPos, yPos, paint);  
  168.             paint.reset();  
  169.         }  
  170.     }  
  171.   
  172. }  

转载于:https://www.cnblogs.com/mochaMM/p/5157277.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐