zoukankan      html  css  js  c++  java
  • Android 获取手机通讯录信息 — 头像、姓名和A-Z的快速查询

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

    具体实现过程如下:

    先在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>


     

  • 相关阅读:
    UVA 12307 Smallest Enclosing Rectangle
    UVALive 4728 Squares
    扩栈代码
    uva 10256 The Great Divide
    uva 11168 Airport
    uva 10625 Board Wrapping
    bzoj千题计划206:bzoj1076: [SCOI2008]奖励关
    NOIP2017 列队
    bzoj3529: [Sdoi2014]数表
    bzoj1966: [Ahoi2005]VIRUS 病毒检测
  • 原文地址:https://www.cnblogs.com/zhangping/p/3521094.html
Copyright © 2011-2022 走看看