首先先看一下效果图再说吧:

具体实现过程如下:

先在AndroidManifest.xml文件中添加读取联系人的权限:

1     <uses-permission android:name="android.permission.READ_CONTACTS" />

联系人列表对应的适配器:

 1 package com.example.testcontacts.adapter;
 2
 3 import java.util.List;
 4
 5 import android.content.Context;
 6 import android.view.View;
 7 import android.view.ViewGroup;
 8 import android.widget.ArrayAdapter;
 9 import android.widget.LinearLayout;
10 import android.widget.SectionIndexer;
11 import android.widget.TextView;
12
13 import com.example.testcontacts.R;
14 import com.example.testcontacts.domain.Contact;
15
16 public class ContactAdapter extends ArrayAdapter<Contact> {
17     private int resource;// 需要渲染的item布局文件
18     private SectionIndexer mIndexer;// 字母表分组工具
19
20     public ContactAdapter(Context context, int textViewResourceId,List<Contact> objects) {
21         super(context, textViewResourceId, objects);
22         resource = textViewResourceId;
23     }
24
25     @Override
26     public View getView(int position, View convertView, ViewGroup parent) {
27         Contact contact = getItem(position);
28         View view = convertView == null ? View.inflate(getContext(),  R.layout.contact_item, null) : convertView;
29         LinearLayout ll_sort_key = (LinearLayout) view.findViewById(R.id.ll_sort_key);
30         TextView tv_sort_key = (TextView) view.findViewById(R.id.tv_sort_key);
31         TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
32         TextView tv_number = (TextView) view.findViewById(R.id.tv_number);
33
34         tv_name.setText(contact.getName());
35         tv_number.setText(contact.getNumber());
36
37         int section = mIndexer.getSectionForPosition(position);
38         if (position == mIndexer.getPositionForSection(section)) {
39             tv_sort_key.setText(contact.getSortKey());
40             ll_sort_key.setVisibility(View.VISIBLE);
41         }else{
42             ll_sort_key.setVisibility(View.GONE);
43         }
44         return view;
45     }
46
47     /**给当前适配器传入一个分组工具*/
48     public void setIndexer(SectionIndexer indexer) {
49         mIndexer = indexer;
50     }
51 }

实体类:

 1 package com.example.testcontacts.domain;
 2
 3 public class Contact {
 4     private String name;// 联系人姓名
 5     private String sortKey;// 排序字母
 6     private String number;
 7
 8     public String getName() {
 9         return name;
10     }
11
12     public void setName(String name) {
13         this.name = name;
14     }
15
16     public String getSortKey() {
17         return sortKey;
18     }
19
20     public void setSortKey(String sortKey) {
21         this.sortKey = sortKey;
22     }
23
24     public String getNumber() {
25         return number;
26     }
27
28     public void setNumber(String number) {
29         this.number = number;
30     }
31 }

java类:

  1 package com.example.testcontacts;
  2
  3 import java.util.ArrayList;
  4 import java.util.List;
  5
  6 import android.app.Activity;
  7 import android.database.Cursor;
  8 import android.net.Uri;
  9 import android.os.Bundle;
 10 import android.provider.ContactsContract;
 11 import android.view.MotionEvent;
 12 import android.view.View;
 13 import android.view.View.OnTouchListener;
 14 import android.view.ViewGroup.MarginLayoutParams;
 15 import android.widget.AbsListView;
 16 import android.widget.AbsListView.OnScrollListener;
 17 import android.widget.AlphabetIndexer;
 18 import android.widget.Button;
 19 import android.widget.LinearLayout;
 20 import android.widget.ListView;
 21 import android.widget.RelativeLayout;
 22 import android.widget.TextView;
 23
 24 import com.example.testcontacts.adapter.ContactAdapter;
 25 import com.example.testcontacts.domain.Contact;
 26
 27 public class MainActivity extends Activity {
 28     private LinearLayout ll_title;// 分组的布局
 29     private RelativeLayout rl_toast;
 30     private Button btn_alphabet;
 31     private TextView tv_title; // 分组上显示的字母
 32     private TextView tv_toast;
 33     private ListView lv_contacts;// 联系人ListView
 34
 35     private ContactAdapter adapter;// 联系人列表适配器
 36     private AlphabetIndexer indexer;// 用于进行字母表分组
 37     private List<Contact> contacts = new ArrayList<Contact>();// 存储所有手机中的联系人
 38     private String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 定义字母表的排序规则
 39     private int lastFirstVisibleItem = -1;// 上次第一个可见元素,用于滚动时记录标识。
 40
 41     @Override
 42     protected void onCreate(Bundle savedInstanceState) {
 43         super.onCreate(savedInstanceState);
 44         setContentView(R.layout.activity_main);
 45
 46         adapter = new ContactAdapter(this, R.layout.contact_item, contacts);
 47         ll_title = (LinearLayout) findViewById(R.id.ll_title);
 48         rl_toast = (RelativeLayout) findViewById(R.id.rl_section_toast);
 49         tv_title = (TextView) findViewById(R.id.tv_title);
 50         tv_toast = (TextView) findViewById(R.id.tv_section_toast);
 51         btn_alphabet = (Button) findViewById(R.id.btn_alphabet);
 52         lv_contacts = (ListView) findViewById(R.id.lv_contacts);
 53
 54         Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
 55         Cursor cursor = getContentResolver().query(uri,
 56                 new String[] { "display_name", "sort_key", }, null, null,
 57                 "sort_key");
 58         if (cursor.moveToFirst()) {
 59             do {
 60                 String name = cursor.getString(0);
 61                 String sortKey = getSortKey(cursor.getString(1));
 62                 Contact contact = new Contact();
 63                 contact.setName(name);
 64                 contact.setSortKey(sortKey);
 65                 contacts.add(contact);
 66             } while (cursor.moveToNext());
 67         }
 68         startManagingCursor(cursor);
 69         indexer = new AlphabetIndexer(cursor, 1, alphabet);
 70         adapter.setIndexer(indexer);
 71         if (contacts.size() > 0) {
 72              setListViewListener();
 73              setAlpabetListener();
 74         }
 75     }
 76
 77     /** 根据当前的滑动状态来改变分组的显示位置,从而实现挤压动画的效果 */
 78     private void setListViewListener() {
 79         lv_contacts.setAdapter(adapter);
 80         lv_contacts.setOnScrollListener(new OnScrollListener() {
 81             @Override
 82             public void onScrollStateChanged(AbsListView view, int scrollState) {
 83             }
 84
 85             @Override
 86             public void onScroll(AbsListView view, int firstVisibleItem,
 87                     int visibleItemCount, int totalItemCount) {
 88                 int section = indexer.getSectionForPosition(firstVisibleItem);//当前分组所在的位置
 89                 int nextSecPosition = indexer.getPositionForSection(section + 1);//找出当前位置所在的分组
 90                 if (firstVisibleItem != lastFirstVisibleItem) {
 91                     MarginLayoutParams params = (MarginLayoutParams) ll_title
 92                             .getLayoutParams();
 93                     params.topMargin = 0;
 94                     ll_title.setLayoutParams(params);
 95                     tv_title.setText(String.valueOf(alphabet.charAt(section)));
 96                 }
 97                 if (nextSecPosition == firstVisibleItem + 1) {
 98                     View childView = view.getChildAt(0);
 99                     if (childView != null) {
100                         int titleHeight = ll_title.getHeight();
101                         int bottom = childView.getBottom();
102                         MarginLayoutParams params = (MarginLayoutParams) ll_title
103                                 .getLayoutParams();
104                         if (bottom < titleHeight) {
105                             float pushedDistance = bottom - titleHeight;
106                             params.topMargin = (int) pushedDistance;
107                             ll_title.setLayoutParams(params);
108                         } else {
109                             if (params.topMargin != 0) {
110                                 params.topMargin = 0;
111                                 ll_title.setLayoutParams(params);
112                             }
113                         }
114                     }
115                 }
116                 lastFirstVisibleItem = firstVisibleItem;
117             }
118         });
119     }
120
121     /**
122      * 获取sort key的首个字符,如果是英文字母就直接返回,否则返回#。
123      * @param sortKeyString 数据库中读取出的sort key
124      * @return 英文字母或者#
125      */
126     private String getSortKey(String sortKeyString) {
127         String key = sortKeyString.substring(0, 1).toUpperCase();
128         if (key.matches("[A-Z]")) {
129             return key;
130         }
131         return "#";
132     }
133
134     /**
135      * 设置字母表上的触摸事件,根据当前触摸的位置结合字母表的高度,计算出当前触摸在哪个字母上。
136      * 当手指按在字母表上时,展示弹出式分组。手指离开字母表时,将弹出式分组隐藏。
137      */
138     private void setAlpabetListener() {
139         btn_alphabet.setOnTouchListener(new OnTouchListener() {
140             @Override
141             public boolean onTouch(View v, MotionEvent event) {
142                 float alphabetHeight = btn_alphabet.getHeight();//获得字母表的总高度
143                 float y = event.getY();//获取到目前手指在字母表上的纵坐标
144                 int sectionPosition = (int) ((y/alphabetHeight)/(1f/27f));//当前手指所在位置(0表在#端,1表示在Z端)。
145                 if (sectionPosition < 0) {
146                     sectionPosition = 0;
147                 } else if (sectionPosition > 26) {
148                     sectionPosition = 26;
149                 }
150                 String sectionLetter = String.valueOf(alphabet.charAt(sectionPosition));
151                 int position = indexer.getPositionForSection(sectionPosition);
152                 switch (event.getAction()) {
153                 case MotionEvent.ACTION_DOWN://在弹出式分组上显示当前手指所按的字母
154                     btn_alphabet.setBackgroundResource(R.drawable.contact_list_scroll_pressed);
155                     rl_toast.setVisibility(View.VISIBLE);
156                     tv_toast.setText(sectionLetter);
157                     lv_contacts.setSelection(position);//把列表滚动到相应的分组
158                     break;
159                 case MotionEvent.ACTION_MOVE://同ACTION_DOWN
160                     tv_toast.setText(sectionLetter);
161                     lv_contacts.setSelection(position);
162                     break;
163                 default://弹出式分组布局隐藏
164                     btn_alphabet.setBackgroundResource(R.drawable.contact_list_scroll_normal);
165                     rl_toast.setVisibility(View.GONE);
166                 }
167                 return true;
168             }
169         });
170     }
171 }

样式:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
 3
 4     <corners
 5         android:bottomLeftRadius="0dp"
 6         android:bottomRightRadius="0dp"
 7         android:topLeftRadius="0dp"
 8         android:topRightRadius="0dp" />
 9
10     <gradient
11         android:angle="90"
12         android:endColor="#8BC4DF"
13         android:startColor="#8BC4DF" />
14
15     <stroke android:width="1dp" />
16
17 </shape>

布局文件:

在res/layout中新建一个布局文件,起名为:activity.main.xml

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6
 7     <ListView
 8         android:id="@+id/lv_contacts"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:layout_alignParentTop="true"
12         android:divider="@drawable/divider1"
13         android:dividerHeight="1dp"
14         android:fadingEdge="none"
15         android:scrollbars="none" >
16     </ListView>
17
18     <LinearLayout
19         android:id="@+id/ll_title"
20         android:layout_width="fill_parent"
21         android:layout_height="18dp"
22         android:layout_alignParentTop="true"
23         android:background="@drawable/itembg" >
24
25         <TextView
26             android:id="@+id/tv_title"
27             android:layout_width="wrap_content"
28             android:layout_height="wrap_content"
29             android:layout_gravity="center_horizontal"
30             android:layout_marginLeft="10dp"
31             android:textColor="#000000"
32             android:textSize="14sp" />
33     </LinearLayout>
34
35     <Button
36         android:id="@+id/btn_alphabet"
37         android:layout_width="wrap_content"
38         android:layout_height="fill_parent"
39         android:layout_alignParentRight="true"
40         android:background="@drawable/contact_list_scroll_normal" />
41
42     <RelativeLayout
43         android:id="@+id/rl_section_toast"
44         android:layout_width="70dp"
45         android:layout_height="70dp"
46         android:layout_centerInParent="true"
47         android:background="@drawable/section_toast"
48         android:visibility="gone" >
49
50         <TextView
51             android:id="@+id/tv_section_toast"
52             android:layout_width="wrap_content"
53             android:layout_height="wrap_content"
54             android:layout_centerInParent="true"
55             android:textColor="#000"
56             android:textSize="30sp" />
57     </RelativeLayout>
58
59 </RelativeLayout>

在res/layout中新建一个布局文件,起名为:contact_item.xml

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5
 6     <LinearLayout
 7         android:id="@+id/ll_sort_key"
 8         android:layout_width="fill_parent"
 9         android:layout_height="18dip"
10         android:background="@drawable/itembg" >
11
12         <TextView
13             android:id="@+id/tv_sort_key"
14             android:layout_width="wrap_content"
15             android:layout_height="wrap_content"
16             android:layout_gravity="center_horizontal"
17             android:layout_marginLeft="10dip"
18             android:text="A"
19             android:textColor="#000000"
20             android:textSize="14sp" />
21     </LinearLayout>
22
23     <LinearLayout
24         android:id="@+id/ll_name"
25         android:layout_width="fill_parent"
26         android:layout_height="50dip" >
27
28         <ImageView
29             android:layout_width="40dp"
30             android:layout_height="40dp"
31             android:layout_gravity="center_vertical"
32             android:layout_marginLeft="10dip"
33             android:layout_marginRight="10dip"
34             android:src="@drawable/icon" />
35
36         <LinearLayout
37             android:layout_width="fill_parent"
38             android:layout_height="fill_parent"
39             android:layout_gravity="top"
40             android:orientation="vertical" >
41
42             <TextView
43                 android:id="@+id/tv_name"
44                 android:layout_width="wrap_content"
45                 android:layout_height="wrap_content"
46                 android:layout_gravity="center_vertical"
47                 android:text="张三"
48                 android:textColor="#000000"
49                 android:textSize="18sp" />
50
51             <TextView
52                 android:id="@+id/tv_number"
53                 android:layout_width="wrap_content"
54                 android:layout_height="wrap_content"
55                 android:layout_gravity="center_vertical"
56                 android:layout_marginTop="10dp"
57                 android:text="186057986"
58                 android:textColor="#88000000"
59                 android:textSize="12sp" />
60         </LinearLayout>
61     </LinearLayout>
62
63 </LinearLayout>

转载于:https://www.cnblogs.com/zhangping/p/3521094.html

Android 获取手机通讯录信息 — 头像、姓名和A-Z的快速查询相关推荐

  1. Android 获取手机通讯录信息 — 头像、姓名和A-Z的快速查询

    具体实现过程如下: 先在AndroidManifest.xml文件中添加读取联系人的权限: 1 <uses-permission android:name="android.permi ...

  2. 获取手机联系人信息(姓名 电话号码)

    手机的联系人信息,存放的位置分为两种.一种存放在手机内存里面,一种是存放在sim卡里面. 他们的访问方式都相似,都是把电话号码和联系人姓名是分开存放在数据库中的,只是访问的uri不同. 本文主要讲的是 ...

  3. android 通过手机号码查询联系人,android获取手机通讯录联系人

    android获取手机通讯录联系人信息 private void getPhoneContacts() { ContentResolver resolver = this.getContentReso ...

  4. android获取手机通讯录联系人

    android获取手机通讯录联系人信息 private void getPhoneContacts() { ContentResolver resolver = this.getContentReso ...

  5. android sim卡联系人存储格式,Android获取手机通讯录、sim卡联系人及调用拨号界面方法...

    android获取手机通讯录联系人信息 private void getPhoneContacts() { ContentResolver resolver = this.getContentReso ...

  6. android获取手机通讯录和sim卡通讯录

    获取手机通讯录 1 权限 <uses-permission android:name="android.permission.READ_CONTACTS"/> 注意6. ...

  7. Android获取手机基站信息并进行基站定位(基站定位原理)

    一,首先普及一下手机基站信息中相关的专业词汇: 通过TelephonyManager 获取lac:mcc:mnc:cell-id(基站信息)的解释:  MCC,Mobile Country Code, ...

  8. android获取手机通讯录

    在android中读取联系人信息的程序,包括读取联系人姓名.手机号码和邮箱 (转载自博客:http://www.cnblogs.com/error404/archive/2013/03/12/2956 ...

  9. Android 获取手机设备信息(厂商,型号等)

    public class DeviceUtils {/*** 获取当前手机系统语言.** @return 返回当前系统语言.例如:当前设置的是"中文-中国",则返回"zh ...

最新文章

  1. VS Code go 插件安装失败 r.declReader.Reset undefined
  2. 概率统计 —— 常犯错误
  3. wps电脑版_WPS的前前前前身,是一根绳子?懂点历史没坏处
  4. 随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
  5. msg计算机指令怎样用,WIN7里使用msg命令发送消息失败
  6. linux sys存放内容,了解linux系统目录,sys,tmp,usr,var!
  7. 之前接触过的测试的相关工具
  8. mysql数据库增加模块_使用bind-mysql模块增加对mysql数据库的支持
  9. 源码分析三:OkHttp(2)—拦截器简介
  10. 机器人操作系统--ROS系统安装配置详细教程及实践
  11. NSSM的下载与使用
  12. _beginThread如何传递多个参数
  13. Python 解析风云四A卫星L1级别数据以及绘制卫星云图
  14. 如何在电脑上装一个虚拟机
  15. Python语言程序设计基础_序列型数据和控制结构综合练习(第七周)_答案_通识教育必修课程_上海师范大学
  16. 如何在 Python 中构建跨平台桌面应用程序
  17. [配置文件]_start.wzd
  18. 基于arduino的幻尔总线机器人
  19. VSS2005安装指南
  20. P02014145 杨志豪 信息论作业

热门文章

  1. KMP算法之NEXT数组代码原理分析 - 数据结构和算法38
  2. php软件开发--linux进阶
  3. scrum项目协作是什么_什么是小型Scrum?
  4. 如何在Raspberry Pi上安装Fedora 25
  5. 开源无人机_开源无人机,欧洲开源等等
  6. (12)css—float浮动样式
  7. 第二十九章:学校招生
  8. HTML readonly
  9. 十一.激光惯导LIO-SLAM框架学习之LIO-SAM框架---框架介绍和运行演示
  10. java 随机手机验证码_基于Java随机生成手机短信验证码的实例代码|chu