最近仿照联系人列表页,发现有现成的组件
需要组件包括:
1.pinned-section-listview (https://github.com/beworker/pinned-section-listview)
2.IndexBar (http://git.oschina.net/droideep/IndexBar)
3.pinyin4j.jar 拼音包 http://vdisk.weibo.com/s/JfPk1
开始码.......
package com.weidingqiang.customchinacar.activities; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; import com.hb.views.PinnedSectionListView; import com.weidingqiang.customchinacar.R; import com.weidingqiang.customchinacar.base.BaseKJActivity; import com.weidingqiang.customchinacar.models.Contact; import net.sourceforge.pinyin4j.PinyinHelper; import org.kymjs.kjframe.ui.BindView; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import io.github.brightyoyo.IndexBar; public class ContactActivity extends BaseKJActivity { /** * 选择乘车人列表有三部分组成 * 1.读取联系人数据 * 2.联系人列表组件 * 3.左边选择组件 */ private static final String TAG = ContactActivity.class.getSimpleName(); private ArrayList<Contact> contacts; //数据集。 private ArrayList<Item> items = null; // ListView之Item的View Type数量。 private final int VIEW_TYPE_COUNT = 2; //已经添加的组 private Map<String,String> addgroups; @BindView(id=R.id.pinnedlist) PinnedSectionListView listView; @BindView(id=R.id.index_bar) IndexBar mIndexBar; @BindView(id=R.id.previewText) TextView mPreviewText; private Map<String, Integer> mSections = new HashMap<String, Integer>(); @Override public void setRootView() { super.setRootView(); setContentView(R.layout.activity_contact); } @Override public void initWidget() { super.initWidget(); listView.setShadowVisible(false); mIndexBar.setIndexBarFilter(new IndexBar.IIndexBarFilter() { @Override public void filterList(float sideIndex, int position, String previewText) { Integer selection = mSections.get(previewText); if (selection != null) { mPreviewText.setVisibility(View.VISIBLE); mPreviewText.setText(previewText); listView.setSelection(selection); } else { mPreviewText.setVisibility(View.GONE); } } }); } @Override public void initData() { super.initData(); contacts = new ArrayList<Contact>(); addgroups = new HashMap<String,String>(); items = new ArrayList<Item>(); mIndexBar.setSections(alphabets()); } /** * 执行在异步,用于做耗时操作 */ @Override public void initDataFromThread() { super.initDataFromThread(); readContacts(contacts); } /** *(initDataFromThread() 执行完成后将会回调) */ @Override protected void threadDataInited() { super.threadDataInited(); int target = 0; for (int k=0;k<contacts.size();k++) { boolean showline = true; //判断是否增加了组 Contact contact = contacts.get(k); if(!isaddGroup(contact.firstLetterOfName())){ mSections.put(contact.firstLetterOfName(), target); showline = false; addgroups.put(contact.firstLetterOfName(),contact.firstLetterOfName()); Item group = new Item(); group.type = Item.GROUP; group.text = contact.firstLetterOfName(); group.showline = showline; items.add(group); target++; } Item child = new Item(); child.type = Item.CHILD; child.text = contact.name; child.phone = contact.getPhone(); child.showline = showline; items.add(child); target++; } listView.setAdapter(new MyAdapter(this, -1)); } private String[] alphabets() { final int length = 26; final String[] alphabets = new String[length]; char c = 'A'; for (int i = 0; i < length; i++) { alphabets[i] = String.valueOf(c++); } return alphabets; } private boolean isaddGroup(String name){ boolean boo = addgroups.containsKey(name); return boo; } //-------------------------------------------------------------------------------------------// private class MyAdapter extends ArrayAdapter<Item> implements PinnedSectionListView.PinnedSectionListAdapter { private LayoutInflater inflater = null; public MyAdapter(Context context, int resource) { super(context, resource); inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { int type = this.getItemViewType(position); if (type == Item.GROUP) { convertView = inflater.inflate( R.layout.contact_list_group_item, null); TextView tv = (TextView) convertView .findViewById(R.id.group_text); tv.setText(getItem(position).text); //tv.setBackgroundColor(getResources().getColor(R.color.contact_list_group_color)); // 将背景设置为半透明,更好的观察效果。 //tv.getBackground().setAlpha(128); } if (type == Item.CHILD) { convertView = inflater.inflate( R.layout.contact_list_item, null); TextView tv = (TextView) convertView .findViewById(R.id.contact_name); tv.setText(getItem(position).text); TextView tvphone = (TextView) convertView .findViewById(R.id.contact_phone); tvphone.setText(getItem(position).phone); if(getItem(position).showline) { View showline = (View) convertView.findViewById(R.id.showlineview); showline.setVisibility(View.VISIBLE); } } return convertView; } @Override public int getItemViewType(int position) { return getItem(position).type; } // 2个type:GROUP或者CHILD。 @Override public int getViewTypeCount() { return VIEW_TYPE_COUNT; } @Override public Item getItem(int position) { Item item = items.get(position); return item; } @Override public int getCount() { return items.size(); } // 假设此方法返回皆为false。那么PinnedSectionListView将退化成为一个基础的ListView. // 只不过退化后的ListView只是一个拥有两个View Type的ListView。 // 从某种角度上讲,此方法对于PinnedSectionListView至关重要,因为返回值true或false,将直接导致PinnedSectionListView是一个PinnedSectionListView,还是一个普通的ListView。 @Override public boolean isItemViewTypePinned(int viewType) { boolean type = false; switch (viewType) { case Item.GROUP: type = true; break; case Item.CHILD: type = false; break; default: type = false; break; } return type; } } //区分组 // 用于承载数据块的类。 // 字段分为类型(type)和值(text)。 private class Item { public static final int GROUP = 0; public static final int CHILD = 1; public int type; public String text; public String phone; public Boolean showline; } //-------------------------------------------------------------------------------------------// // 读取设备联系人的一般方法。大致流程就是这样,模板化的操作代码。 private void readContacts(ArrayList<Contact> contacts) { Uri uri = Uri.parse("content://com.android.contacts/contacts"); ContentResolver reslover = this.getContentResolver(); // 在这里我们给query传递进去一个SORT_KEY_PRIMARY。 // 告诉ContentResolver获得的结果安装联系人名字的首字母有序排列。 Cursor cursor = reslover.query(uri, null, null, null, android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY); while (cursor.moveToNext()) { // 联系人ID String id = cursor .getString(cursor .getColumnIndex(android.provider.ContactsContract.Contacts._ID)); // Sort Key,读取的联系人按照姓名从 A->Z 排序分组。 String sort_key_primary = cursor .getString(cursor .getColumnIndex(android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY)); // 获得联系人姓名 String name = cursor .getString(cursor .getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME)); Contact mContact = new Contact(); mContact.id = id; mContact.name = name; mContact.sort_key_primary = getPinYinHeadChar(sort_key_primary); // 获得联系人手机号码 Cursor phone = reslover.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id, null, null); // 取得电话号码(可能存在多个号码) // 因为同一个名字下,用户可能存有一个以上的号, // 遍历。 ArrayList<String> phoneNumbers = new ArrayList<String>(); while (phone.moveToNext()) { int phoneFieldColumnIndex = phone .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); String phoneNumber = phone.getString(phoneFieldColumnIndex); phoneNumbers.add(phoneNumber); } mContact.phoneNumbers = phoneNumbers; contacts.add(mContact); } } /** * 提取每个汉字的首字母 * 用了一个拼音包 * @param str * @return String */ public static String getPinYinHeadChar(String str) { String convert = ""; for (int j = 0; j < str.length(); j++) { char word = str.charAt(j); // 提取汉字的首字母 String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word); if (pinyinArray != null) { convert += pinyinArray[0].charAt(0); } else { convert += word; } } return convert; } }
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aCar="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:orientation="vertical" > <com.weidingqiang.customchinacar.views.topbar.BaseTopBar android:id="@+id/baseTopBar" android:layout_width="match_parent" android:layout_height="@dimen/topbar_hight" aCar:isShowMiddleTextView = "true" aCar:middleText = "@string/qctivity_contact_title" aCar:isShowRight = "false" > </com.weidingqiang.customchinacar.views.topbar.BaseTopBar> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" > <com.hb.views.PinnedSectionListView android:id="@+id/pinnedlist" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginRight="26dp" /> <TextView android:id="@+id/previewText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textSize="40sp" android:textStyle="bold" android:textColor="@color/black" /> <io.github.brightyoyo.IndexBar android:id="@+id/index_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_margin="5dp" aCar:alphabetPadding="5dp" aCar:alphabetTextColor="#DFAF3F" aCar:alphabetTextSize="12sp" aCar:indexBarColorNormal="@android:color/transparent" aCar:indexBarColorPressed="#56000000" aCar:indexBarRound="5dp" aCar:withinIndexBar="true" /> </RelativeLayout> </LinearLayout>
package com.weidingqiang.customchinacar.models;
import java.util.ArrayList;
/**
* Created by weidingqiang on 15/11/12.
*/
// 用于装载从联系人数据库中读取到的数据。
// 结构化数据,便于数据操作和访问。
public class Contact {
public String id;
public String name;
public String sort_key_primary;
public ArrayList<String> phoneNumbers;
//获得一个联系人名字的首字符。
//比如一个人的名字叫“安卓”,那么这个人联系人的首字符是:A。
public String firstLetterOfName(){
String s=sort_key_primary.charAt(0)+"";
return s.toUpperCase();
}
public String getPhoneNumbers() {
String phones = " ";
for (int i = 0; i < phoneNumbers.size(); i++) {
phones += "号码" + i + ":" + phoneNumbers.get(i);
}
return phones;
}
public String getPhone(){
if(phoneNumbers.size() == 0)
return "";
return phoneNumbers.get(0);
}
}