Android之实现系统联系人软件的分组和字母提示效果


联系人分章节显示以及ListView快速滑动显示联系人首字母例子,查阅网上很多这样的例子后,发现普遍是从系统源码里面抽取的,而且普遍比较复杂,这里做了精简,扩展性较强,移植起来非常方便。

1.FastContactSearchDemoActivity.java

 
  1. package com.zhf.FastContactSearchDemo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collections;  
  5. import java.util.HashMap;  
  6. import java.util.List;  
  7. import java.util.Set;  
  8. import java.util.regex.Pattern;  
  9. import Android.app.Activity;  
  10. import android.content.AsyncQueryHandler;  
  11. import android.content.ContentResolver;  
  12. import android.content.ContentValues;  
  13. import android.content.Context;  
  14. import android.database.Cursor;  
  15. import android.net.Uri;  
  16. import android.os.Bundle;  
  17. import android.view.LayoutInflater;  
  18. import android.view.View;  
  19. import android.view.ViewGroup;  
  20. import android.widget.BaseAdapter;  
  21. import android.widget.ListView;  
  22. import android.widget.SectionIndexer;  
  23. import android.widget.TextView;  
  24.   
  25. /** 
  26.  * 联系人分章节显示以及ListView快速滑动显示联系人首字母例子 
  27.  * 本例来自http://blog.csdn.net/luck_apple/article/details/6741860 
  28.  * 查阅网上很多这样的例子后,发现普遍是从系统源码里面抽取的,而且普遍比较复杂,这里做了精简,扩展性较强,移植起来非常方便。 
  29.  * @author hiphonezhu@sina.com 
  30.  *  
  31.  */  
  32. public class FastContactSearchDemoActivity extends Activity {  
  33.     private BaseAdapter adapter;  
  34.     private ListView personList;  
  35.     private AsyncQueryHandler asyncQuery;  
  36.     private static final String NAME = "name", NUMBER = "number",  
  37.             SORT_KEY = "sort_key";  
  38.   
  39.     @Override  
  40.     public void onCreate(Bundle savedInstanceState) {  
  41.         super.onCreate(savedInstanceState);  
  42.         setContentView(R.layout.main);  
  43.         personList = (ListView) findViewById(R.id.listView);  
  44.         asyncQuery = new MyAsyncQueryHandler(getContentResolver());  
  45.     }  
  46.   
  47.     @Override  
  48.     protected void onResume() {  
  49.         super.onResume();  
  50.         Uri uri = Uri.parse("content://com.android.contacts/data/phones"); // 联系人的Uri  
  51.         String[] projection = { "_id""display_name""data1""sort_key" }; // 查询的列   
  52.         asyncQuery.startQuery(0, null, uri, projection, nullnull,  
  53.                 "sort_key COLLATE LOCALIZED asc"); // 按照sort_key升序查询   
  54.     }  
  55.   
  56.     /** 
  57.      * 数据库异步查询类AsyncQueryHandler 
  58.      *  
  59.      * @author administrator 
  60.      *  
  61.      */  
  62.     private class MyAsyncQueryHandler extends AsyncQueryHandler {  
  63.   
  64.         public MyAsyncQueryHandler(ContentResolver cr) {  
  65.             super(cr);  
  66.   
  67.         }  
  68.   
  69.         /** 
  70.          * 查询结束的回调函数 
  71.          */  
  72.         @Override  
  73.         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {  
  74.             if (cursor != null && cursor.getCount() > 0) {  
  75.                 List<ContentValues> list = new ArrayList<ContentValues>();  
  76.                 cursor.moveToFirst();  
  77.                 for (int i = 0; i < cursor.getCount(); i++) {  
  78.                     ContentValues cv = new ContentValues();  
  79.                     cursor.moveToPosition(i);  
  80.                     String name = cursor.getString(1);  
  81.                     String number = cursor.getString(2);  
  82.                     String sortKey = cursor.getString(3);  
  83.   
  84.                     if (number.startsWith("+86")) {// 去除多余的中国地区号码标志,对这个程序没有影响。   
  85.                         cv.put(NAME, name);  
  86.                         cv.put(NUMBER, number.substring(3));  
  87.                         cv.put(SORT_KEY, sortKey);  
  88.                     } else {  
  89.                         cv.put(NAME, name);  
  90.                         cv.put(NUMBER, number);  
  91.                         cv.put(SORT_KEY, sortKey);  
  92.                     }  
  93.                     list.add(cv);  
  94.                 }  
  95.                 if (list.size() > 0) {  
  96.                     setAdapter(list);  
  97.                 }  
  98.             }  
  99.         }  
  100.   
  101.     }  
  102.   
  103.     private void setAdapter(List<ContentValues> list) {  
  104.         adapter = new ListAdapter(this, list);  
  105.         personList.setAdapter(adapter);  
  106.   
  107.     }  
  108.   
  109.     private static class ViewHolder {  
  110.         TextView alpha;  
  111.         TextView name;  
  112.         TextView number;  
  113.     }  
  114.   
  115.     /** 
  116.      * 其他项目使用时,只需要传进来一个有序的list即可 
  117.      */  
  118.     private class ListAdapter extends BaseAdapter implements SectionIndexer {  
  119.         private LayoutInflater inflater;  
  120.         private List<ContentValues> list;  
  121.         private HashMap<String, Integer> alphaIndexer;//保存每个索引在list中的位置【#-0,A-4,B-10】   
  122.         private String[] sections;//每个分组的索引表【A,B,C,F...】   
  123.   
  124.         public ListAdapter(Context context, List<ContentValues> list) {  
  125.             this.inflater = LayoutInflater.from(context);  
  126.             this.list = list; // 该list是已经排序过的集合,有些项目中的数据必须要自己进行排序。   
  127.             this.alphaIndexer = new HashMap<String, Integer>();  
  128.   
  129.             for (int i =0; i <list.size(); i++) {  
  130.                 String name = getAlpha(list.get(i).getAsString(SORT_KEY));  
  131.                 if(!alphaIndexer.containsKey(name)){//只记录在list中首次出现的位置   
  132.                     alphaIndexer.put(name, i);  
  133.                 }  
  134.             }  
  135.             Set<String> sectionLetters = alphaIndexer.keySet();  
  136.             ArrayList<String> sectionList = new ArrayList<String>(  
  137.                     sectionLetters);  
  138.             Collections.sort(sectionList);  
  139.             sections = new String[sectionList.size()];  
  140.             sectionList.toArray(sections);  
  141.         }  
  142.   
  143.         @Override  
  144.         public int getCount() {  
  145.             return list.size();  
  146.         }  
  147.   
  148.         @Override  
  149.         public Object getItem(int position) {  
  150.             return list.get(position);  
  151.         }  
  152.   
  153.         @Override  
  154.         public long getItemId(int position) {  
  155.             return position;  
  156.         }  
  157.   
  158.         @Override  
  159.         public View getView(int position, View convertView, ViewGroup parent) {  
  160.             ViewHolder holder;  
  161.   
  162.             if (convertView == null) {  
  163.                 convertView = inflater.inflate(R.layout.list_item, null);  
  164.                 holder = new ViewHolder();  
  165.                 holder.alpha = (TextView) convertView.findViewById(R.id.alpha);  
  166.                 holder.name = (TextView) convertView.findViewById(R.id.name);  
  167.                 holder.number = (TextView) convertView  
  168.                         .findViewById(R.id.number);  
  169.                 convertView.setTag(holder);  
  170.             } else {  
  171.                 holder = (ViewHolder) convertView.getTag();  
  172.             }  
  173.             ContentValues cv = list.get(position);  
  174.             String name = cv.getAsString(NAME);  
  175.             String number = cv.getAsString(NUMBER);  
  176.             holder.name.setText(name);  
  177.             holder.number.setText(number);  
  178.   
  179.             // 当前联系人的sortKey   
  180.             String currentStr = getAlpha(list.get(position).getAsString(  
  181.                     SORT_KEY));  
  182.             // 上一个联系人的sortKey   
  183.             String previewStr = (position - 1) >= 0 ? getAlpha(list.get(  
  184.                     position - 1).getAsString(SORT_KEY)) : " ";  
  185.             /** 
  186.              * 判断显示#、A-Z的TextView隐藏与可见 
  187.              */  
  188.             if (!previewStr.equals(currentStr)) { // 当前联系人的sortKey!=上一个联系人的sortKey,说明当前联系人是新组。   
  189.                 holder.alpha.setVisibility(View.VISIBLE);  
  190.                 holder.alpha.setText(currentStr);  
  191.             } else {  
  192.                 holder.alpha.setVisibility(View.GONE);  
  193.             }  
  194.             return convertView;  
  195.         }  
  196.   
  197.         /* 
  198.          * 此方法根据联系人的首字母返回在list中的位置 
  199.          */  
  200.         @Override  
  201.         public int getPositionForSection(int section) {  
  202.             String later = sections[section];  
  203.             return alphaIndexer.get(later);  
  204.         }  
  205.   
  206.         /* 
  207.          * 本例中可以不考虑这个方法 
  208.          */  
  209.         @Override  
  210.         public int getSectionForPosition(int position) {  
  211.             String key = getAlpha(list.get(position).getAsString(SORT_KEY));  
  212.             for (int i = 0; i < sections.length; i++) {  
  213.                 if (sections[i].equals(key)) {  
  214.                     return i;  
  215.                 }  
  216.             }  
  217.             return 0;  
  218.         }  
  219.   
  220.         @Override  
  221.         public Object[] getSections() {  
  222.             return sections;  
  223.         }  
  224.     }  
  225.   
  226.     /** 
  227.      * 提取英文的首字母,非英文字母用#代替 
  228.      *  
  229.      * @param str 
  230.      * @return 
  231.      */  
  232.     private String getAlpha(String str) {  
  233.         if (str == null) {  
  234.             return "#";  
  235.         }  
  236.   
  237.         if (str.trim().length() == 0) {  
  238.             return "#";  
  239.         }  
  240.   
  241.         char c = str.trim().substring(0, 1).charAt(0);  
  242.         // 正则表达式,判断首字母是否是英文字母   
  243.         Pattern pattern = Pattern.compile("^[A-Za-z]+{1}quot;);  
  244.         if (pattern.matcher(c + "").matches()) {  
  245.             return (c + "").toUpperCase(); // 大写输出   
  246.         } else {  
  247.             return "#";  
  248.         }  
  249.     }  
  250. }  

  • 1
  • 2
  • 下一页

相关内容