网上Android联系人列表的样例也非常多,都和微信的联系人差点儿相同,因为项目用到了联系人列表索引功能(产品把字母item给去掉了),只是也还是好实现。这里我也来分享分享我的实现,免得以后忘了。那先看看效果(Demo在结尾有下载地址):

要达到的效果就是这么简单。

先说说思路吧:首先为联系人对象加入一个pinyin字段,当获取到了联系人原始数据后,把每一个联系人的名字转换为拼音。并为pinyin字段设置值。

然后获取联系人中出现过哪些字母的拼音保存为数组(这就是字母的item),然后和联系人拼音再组合成新的数组,利用Arrays.sort排序功能,就依次按字母顺序拍好了联系人列表,接下来就是把字母在联系人列表中出现的位置给保存起来,绘制右边字母索引时,给对应的字母设置当前字母在联系人列表的位置,滑动到某一个字母是,就把listview移动到那个位置即可了。

一:先看看提取联系人中出现的字母,并排序

  1. /**
  2. * 把数据排序。并把A-Z顺序加进去
  3. *
  4. * @param carTypes
  5. * @return
  6. */
  7. public String[] sortIndex(List<ConstastBean> constastBeans) {
  8. TreeSet<String> set = new TreeSet<String>();
  9. for (ConstastBean constastBean : constastBeans) {
  10. char ch = constastBean.getPinyin().charAt(0);
  11. set.add(String.valueOf(ch).toUpperCase(Locale.getDefault()));// 获取出现的首字母
  12. }
  13. String[] names = new String[constastBeans.size() + set.size()];// 新数组,用于保存首字母 + 联系人拼音
  14. int i = 0;
  15. for (String string : set) { // 把set中的字母加入到新数组中(前面)
  16. names[i] = string;
  17. i++;
  18. }
  19. <span style="white-space:pre"> </span>//把联系人拼音提取到一个数组中
  20. String[] pyheader = new String[constastBeans.size()];
  21. for (int j = 0; j < constastBeans.size(); j++) {
  22. pyheader[j] = constastBeans.get(j).getPinyin();
  23. }
  24.  
  25. System.arraycopy(pyheader, 0, names, set.size(), pyheader.length);// <span style="font-family: Arial, Helvetica, sans-serif;">把联系人拼音加入到后面,结果就是联系人拼音和出现过的首字母在一个数组里面(是无序的)</span>
  26.  
  27. // 自己主动依照首字母排序
  28. Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);// 严格依照字母顺序排序,忽略字母大写和小写,结果为按拼音排序的数组返回
  29. return names;
  30.  
  31. }

这个返回的就是排好序的字母顺序了(如[A, 安妮,G,盖伦...Z])。

二:接下来就是依据返回的顺序,把联系人对象排序

  1. /**
  2. * 依据名字排序对数据进行排序 由于默认是数字在首位,为了把数字排到末尾,须要进行转换
  3. *
  4. * @param arry
  5. * @return
  6. */
  7. public ArrayList<ConstastBean> getAllLists(String[] arry)
  8. {
  9. ArrayList<ConstastBean> lists = new ArrayList<ConstastBean>();// 保存排好序的数据
  10. ArrayList<ConstastBean> lists2 = new ArrayList<ConstastBean>();// 保存数字开头的数据
  11. ArrayList<ConstastBean> lists3 = new ArrayList<ConstastBean>();// 保存字母数据
  12. // 对数据进行排序
  13. for(int i = 0; i < arry.length; i++)
  14. {
  15. for(int j = 0; j < sourceData.size(); j++)
  16. {
  17. if(arry[i].equals(sourceData.get(j).getPinyin()))
  18. {
  19. lists.add(sourceData.get(j));
  20. break;
  21. }
  22. // else //须要显示单个字母的item,这里就不用凝视。在adapter中应给为这个item单独设置一个布局
  23. // {
  24. // ConstastBean contactBean = new ConstastBean();
  25. // contactBean.setPinyin(arry[i]);
  26. // contactBean.setNickName(arry[i]);
  27. // lists.add(contactBean);
  28. // break;
  29. // }
  30. }
  31. }
  32. // 分离出数字数据和字母数据
  33. int index = getLetter(lists);// 获取字母开头的位置
  34. for(int i = 0; i < lists.size(); i++)
  35. {
  36. if(i < index)
  37. {
  38. lists2.add(lists.get(i));
  39. }
  40. else
  41. {
  42. lists3.add(lists.get(i));
  43. }
  44. }
  45. lists.clear();
  46. lists.addAll(lists3);
  47. lists.addAll(lists2);
  48.  
  49. return lists;
  50. }

因为排好序的是数字在字母前面,可是这里须要数字在后面,所以先查询第一个字母出现的位置。然后从那个位置截取为2个集合。再把数字集合加入到字母集合后面即可了。

三:初始化工作都做好了。就该遍历获取每一个字母所相应的位置了

  1. <span style="white-space:pre"> </span>selector = new HashMap<String, Integer>();
  2. // 遍历排好序的数据,获取每一个字母的位置
  3. for (int i = 0; i < indexStr.length; i++) {
  4. for (int j = 0; j < datas.size(); j++) {
  5. if (datas.get(j).getPinyin().toLowerCase(Locale.getDefault()).startsWith(indexStr[i<span style="white-space:pre"> </span>].toLowerCase(Locale.getDefault()))) {
  6. selector.put(indexStr[i], j);
  7. break;
  8. }
  9. String pinyin = datas.get(j).getPinyin();
  10. if(indexStr[i].equals("#") && isNumeric(pinyin.substring(0,1)))
  11. {
  12. selector.put(indexStr[i], j);
  13. return;
  14. }
  15. }
  16. }

返回的结果就类似于这样的:{D=2, #=23, E=4, G=5, A=0, L=11, M=12, N=14, H=6, J=8, K=10, T=19, V=20, S=16, R=15, Z=21}

  1. /**
  2. * 绘制索引条
  3. */
  4. public void drawIndexView() {
  5. LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, height);
  6. for (int i = 0; i < indexStr.length; i++) {
  7. TextView tv = new TextView(this);
  8. tv.setLayoutParams(params);
  9. tv.setText(indexStr[i]);
  10. tv.setGravity(Gravity.CENTER);
  11. tv.setTextColor(this.getResources().getColor(R.color.indexs_color));
  12. tv.setTextSize(13);
  13.  
  14. layoutIndex.addView(tv);
  15.  
  16. layoutIndex.setOnTouchListener(new OnTouchListener() {
  17.  
  18. @Override
  19. public boolean onTouch(View v, MotionEvent event) {
  20. // TODO Auto-generated method stub
  21. float y = event.getY();
  22. int index = (int) y / height;// 得到点击字母位置的索引
  23. String key = "";
  24. if (index < indexStr.length && index > -1) {
  25. key = indexStr[index];
  26. if (selector.containsKey(key)) {
  27. int position = selector.get(key);
  28. if (listView.getHeaderViewsCount() > 0) {// 加入的header给去掉
  29. listView.setSelectionFromTop(
  30. position + listView.getHeaderViewsCount(), 0);
  31. } else {
  32. listView.setSelectionFromTop(position, 0);// 滑动到第一项
  33. }
  34. }
  35. if (key.equals("↑"))
  36. {
  37. listView.setSelectionFromTop(0, 0);// 滑动到第一项
  38. }
  39. }
  40. if(!key.equals(""))
  41. {
  42. showTv.setText(key);
  43. showTv.setVisibility(View.VISIBLE);
  44. }
  45.  
  46. switch (event.getAction()) {
  47. case MotionEvent.ACTION_UP:
  48. case MotionEvent.ACTION_CANCEL:
  49. case MotionEvent.ACTION_OUTSIDE:
  50. showTv.setVisibility(View.GONE);
  51. break;
  52. case MotionEvent.ACTION_DOWN:
  53. // layoutIndex.setBackground();
  54. break;
  55. }
  56.  
  57. return true;
  58. }
  59. });
  60. }
  61. }

这样就完毕了带索引的联系人列表的实现:Demo源代码下载

Android带索引联系人列表的更多相关文章

  1. Android UI(五)云通讯录项目之联系人列表,带侧滑选择,带搜索框

    作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节.交流QQ群:[编程之美 365234583]h ...

  2. 【Android Developers Training】 98. 获取联系人列表

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

  3. Android实现SQLite数据库联系人列表

    Android实现SQLite数据库联系人列表 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个通讯录查看程序: 要求使用SQLite ...

  4. Android实现“是否退出”对话框和“带图标的列表”对话框

    今天我们学习的内容是实现两种对话框(Dialog),第一种是询问是否退出对话框,另外一种是带图标的列表对话框,程序的执行效果是,我们点击button1的时候,弹出第一种对话框,我们点击button2的 ...

  5. Android Phonebook编写联系人UI加载及联系人保存流程(三)

    2014-01-07 09:54:13  将百度空间里的东西移过来. 本文从点击“添加联系人”Button开始,分析新建联系人页面UI是如何加载,以及新的联系人信息是如何保存的,借此,我们一探Phon ...

  6. Android 读取手机联系人、拨号、发送短信及长按菜单的操作

    本示例实现了读取手机联系人,拨号.发送短信及长按出现菜单选项的操作↓ 1.Andrid项目结构图↓主要操作图中红色方框内的文件. 2.首先布局代码如下↓ a, main.xml 程序运行的主界面,主要 ...

  7. 动手分析安卓仿QQ联系人列表TreeView控件

    因项目需要需要用到仿QQ联系人列表的控件样式,于是网上找到一个轮子(https://github.com/TealerProg/TreeView),工作完成现在简单分析一下这个源码.   一. 需要用 ...

  8. 列表的初识,列表的索引切片,列表的增删改查,列表的嵌套,元组的初识,range

    1 内容总览 列表的初识 列表的索引切片 列表的增删改查 列表的嵌套 元组的初识(了解) 元组的简单应用(了解) range 2 具体内容 列表的初识 why: str: 存储少量的数据.切片出来全都 ...

  9. C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表

    /* ---------------------------------------------------------- 文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:splashc ...

随机推荐

  1. SpringCloud学习笔记(18)----Spring Cloud Netflix之服务网关Zuul原理

    1. Zuul的工作机制 Zuul提供了一个框架,可以对过滤器进行动态的加载,编译,运行.过滤器之间没有直接的相互通信,他们是通过一个RequestContext的静态类来进行数据传递的.Requet ...

  2. How Javascript works (Javascript工作原理) (七) WebAssembly 对比 JavaScript 及其使用场景

    个人总结: 1.webworkers实现了用多线程浏览器来进行多线程操作js的能力. 2.web workers不能操作dom,window,document等对象,一般用于cpu计算型的任务.   ...

  3. javascript的var声明变量和不用var声明变量在全局作用域的区别;

    在全局作用域下,使用var定义的变量不可以delete,没有var 定义的变量可以delete.也就说明隐含全局变量严格来说不是真正的变量,而是全局对象的属性,因为属性可以通过delete删除,而变量 ...

  4. 抓取豆瓣的电影排行榜TOP100

    #!/usr/bin/env python # -*- coding:utf-8 -*- """ 一个简单的Python爬虫, 用于抓取豆瓣电影Top前100的电影的名称 ...

  5. 线性规划(LP)资料下载

    1.学习用PPT harvard gondzio IOE610 mit cxg286 含matlab程序 2.测试库 BPMPD netlib fsu 3.软件测试 BENCHMARKS FOR OP ...

  6. python 模块一览

    一个模块可以对应一个文件 同一个模块,可以import多次,但只会被导入一次 模块的导入顺序 导入模块写在文件最上面 自己写的和内置的以及扩展的分开 顺序:内置,扩展,自己写的 按字母大小写排序 一行 ...

  7. NYIST 1006 偷西瓜

    偷西瓜 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 对于农村的孩子来说最大的乐趣,莫过于和小伙伴们一块下地偷西瓜了,虽然孩子们条件不是很好,但是往往他们很聪明,他 ...

  8. Qt资料大全

    简述 发福利了.发福利了.发福利了,重要的事情说三遍... 为了方便更多Qter了解.学习Qt,现将相关资源进行整理,主要内容包括:Qt官网.编码风格.GitHub & Third-Party ...

  9. Qt之自定义布局管理器(QCardLayout)

    简述 手动布局另一种方法是通过继承QLayout类编写自己的布局管理器. 下面我们详细来举一个例子-QCardLayout.它由同名的Java布局管理器启发而来.也被称之为卡片布局,每个项目偏移QLa ...

  10. a+=b 等价于 a=a+b ?

    a += b和a = a + b全然等价么(java)?可能非常多人以为是一样的,事实上并不是等价的,以下看一下证据吧. public class Test { public static void ...