你的位置:首页 > 操作系统

[操作系统]基于PinnedSectionListView实现联系人通讯录


PinnedSectionListView具体下载地址、使用方法和注意事项:http://www.cnblogs.com/zzw1994/p/4997601.html

怎么根据联系人姓名首字符顺序读取联系人:http://www.cnblogs.com/zzw1994/p/4998524.html

 

 1 <RelativeLayout ="http://schemas.android.com/apk/res/android" 2   ="http://schemas.android.com/tools" 3   android:layout_width="match_parent" 4   android:layout_height="match_parent" 5   > 6  7   <com.zzw.contacts.PinnedSectionListView 8     android:id="@+id/listView" 9     android:layout_width="match_parent"10     android:layout_height="match_parent" />11 12 </RelativeLayout>

activity_main.

权限:

1   <!-- 写权限 -->2   <uses-permission android:name="android.permission.WRITE_CONTACTS" />3   <!-- 读权限 -->4   <uses-permission android:name="android.permission.READ_CONTACTS" />

主要实现代码:

 1 package com.zzw.contacts; 2  3 import java.util.ArrayList; 4  5 import com.zzw.contacts.PinnedSectionListView.PinnedSectionListAdapter; 6  7 import android.app.Activity; 8 import android.content.ContentResolver; 9 import android.content.Context; 10 import android.database.Cursor; 11 import android.graphics.Color; 12 import android.net.Uri; 13 import android.os.Bundle; 14 import android.provider.ContactsContract; 15 import android.view.LayoutInflater; 16 import android.view.View; 17 import android.view.ViewGroup; 18 import android.widget.ArrayAdapter; 19 import android.widget.TextView; 20  21 public class MainActivity extends Activity { 22  23   @Override 24   protected void onCreate(Bundle savedInstanceState) { 25     super.onCreate(savedInstanceState); 26     setContentView(R.layout.activity_main); 27  28     ArrayList<Contact> contacts = new ArrayList<Contact>(); 29     readContacts(contacts); 30  31     final ArrayList<Item> items = new ArrayList<Item>(); 32  33     // 从字母A开始到Z。26个字母,遍历联系人中的首字符是否相等。 34     // 相等则归入一组。 35     int A = (int) 'A'; 36     for (int i = 0; i < 26; i++) { 37       int letter = A + i; 38       char c = (char) letter; 39  40       Item group = new Item(); 41       group.type = Item.GROUP; 42       group.text = c + ""; 43       items.add(group); 44  45       for (int j = 0; j < contacts.size(); j++) { 46         Contact contact = contacts.get(j); 47         String s = contact.firstLetterOfName(); 48         if (s.equals(group.text)) { 49           Item child = new Item(); 50           child.type = Item.CHILD; 51           child.text = contact.name + " " + contact.getPhoneNumbers(); 52           child.contact = contact; 53           items.add(child); 54         } 55       } 56     } 57  58     PinnedSectionListView listView = (PinnedSectionListView) findViewById(R.id.listView); 59  60     ArrayAdapter<Item> adapter = new MyAdapter(this, -1, items); 61     listView.setAdapter(adapter); 62   } 63  64   private class MyAdapter extends ArrayAdapter<Item>implements PinnedSectionListAdapter { 65  66     private LayoutInflater inflater; 67     private ArrayList<Item> items; 68  69     public MyAdapter(Context context, int resource, ArrayList<Item> items) { 70       super(context, resource, items); 71       this.items = items; 72       inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 73     } 74  75     @Override 76     public int getCount() { 77       return items.size(); 78     } 79  80     @Override 81     public int getItemViewType(int position) { 82  83       return items.get(position).type; 84     } 85  86     @Override 87     public int getViewTypeCount() { 88  89       return 2; 90     } 91  92     @Override 93     public Item getItem(int position) { 94       return items.get(position); 95     } 96  97     @Override 98     public View getView(int position, View convertView, ViewGroup parent) { 99 100       String text = getItem(position).text;101 102       switch (getItemViewType(position)) {103       case Item.GROUP:104 105         if (convertView == null) {106           convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);107         }108 109         TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);110 111         // 首字符,分组的依据112         text1.setText(text);113         text1.setBackgroundColor(Color.GRAY);114 115         break;116 117       case Item.CHILD:118         if (convertView == null) {119           convertView = inflater.inflate(android.R.layout.simple_list_item_2, null);120         }121 122         TextView text2 = (TextView) convertView.findViewById(android.R.id.text2);123         text2.setText(text);124 125         break;126       }127       return convertView;128     }129 130     // 假设此方法返回皆为false。那么PinnedSectionListView将退化成为一个基础的ListView.131     // 只不过退化后的ListView只是一个拥有两个View Type的ListView。132     // 从某种角度上讲,此方法对于PinnedSectionListView至关重要,因为返回值true或false,133     // 将直接导致PinnedSectionListView是一个PinnedSectionListView,还是一个普通的ListView。134     @Override135     public boolean isItemViewTypePinned(int viewType) {136       boolean type = false;137       switch (viewType) {138       case Item.GROUP:139         type = true;140         break;141 142       case Item.CHILD:143         type = false;144         break;145 146       default:147         type = false;148         break;149       }150       return type;151     }152 153   }154 155   // 读取设备联系人的一般方法。大致流程就是这样,模板化的操作代码。156   private void readContacts(ArrayList<Contact> contacts) {157     Uri uri = Uri.parse("content://com.android.contacts/contacts");158     ContentResolver resolver = this.getContentResolver();159 160     // 在这里我们给query传递进去一个SORT_KEY_PRIMARY161     // 告诉ContentResolver获得的结果按照联系人名字的首字母有序排序162     Cursor cursor = resolver.query(uri, null, null, null,163         android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY);164 165     while (cursor.moveToNext()) {166       // 联系人id167       String id = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));168       // Sort key,读取的联系人按照姓名从 A->Z 的排序分组169       String sork_key_primary = cursor170           .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY));171       // 获取联系人姓名172       String name = cursor173           .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));174 175       Contact mContact = new Contact();176       mContact.id = id;177       mContact.sort_key_primay = sork_key_primary;178       mContact.name = name;179 180       // 获取联系人的手机号码181       Cursor phone = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,182           ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id, null, null);183       // 取得电话号码(可能存在多个号码)184       // 因为在同一个名字下,用户可能存有一个以上号码185       // 遍历186       ArrayList<String> phoneNumbers = new ArrayList<String>();187       while (phone.moveToNext()) {188         int phoneFieldColumnIndex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);189         String phoneNumber = phone.getString(phoneFieldColumnIndex);190         phoneNumbers.add(phoneNumber);191       }192 193       mContact.phoneNumbers = phoneNumbers;194       contacts.add(mContact);195     }196   }197 198   // 用于承载数据块的类。199   // 字段分为类型(type)和值(text)。200   private class Item {201     public static final int GROUP = 0;202     public static final int CHILD = 1;203 204     public int type;205     public String text;206 207     public Contact contact = null;208   }209 210   // 用于装载从联系人数据库中读取到的数据。211   // 结构化数据,便于数据操作和访问。212   private class Contact {213     public String id;214     public String name;215     public String sort_key_primay;216     public ArrayList<String> phoneNumbers;217 218     // 获得一个联系人名字的首字母。219     // 比如一个人的名字叫做“安卓”,那么这个人的首字母是:A220     public String firstLetterOfName() {221       String s = sort_key_primay.charAt(0) + "";222 223       return s.toUpperCase();224     }225 226     public String getPhoneNumbers() {227       String phones = "";228       for (int i = 0; i < phoneNumbers.size(); i++) {229         phones += ":   " + phoneNumbers.get(i);230       }231       return phones;232     }233   }234 }