您的位置:首页 > 移动开发 > Android开发

Android之实现系统联系人软件的分组和字母提示效果

2014-06-20 09:23 441 查看
联系人分章节显示以及ListView快速滑动显示联系人首字母例子,查阅网上很多这样的例子后,发现普遍是从系统源码里面抽取的,而且普遍比较复杂,这里做了精简,扩展性较强,移植起来非常方便。

1.FastContactSearchDemoActivity.java

[javascript] view
plaincopyprint?

package com.zhf.FastContactSearchDemo;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashMap;

import java.util.List;

import java.util.Set;

import java.util.regex.Pattern;

import android.app.Activity;

import android.content.AsyncQueryHandler;

import android.content.ContentResolver;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ListView;

import android.widget.SectionIndexer;

import android.widget.TextView;

/**

* 联系人分章节显示以及ListView快速滑动显示联系人首字母例子

* 本例来自http://blog.csdn.net/luck_apple/article/details/6741860

* 查阅网上很多这样的例子后,发现普遍是从系统源码里面抽取的,而且普遍比较复杂,这里做了精简,扩展性较强,移植起来非常方便。

* @author hiphonezhu@sina.com

*

*/

public class FastContactSearchDemoActivityextends Activity
{

private BaseAdapter
adapter;

private ListView
personList;

private AsyncQueryHandler
asyncQuery;

private staticfinal String
NAME ="name", NUMBER ="number",

SORT_KEY = "sort_key";

@Override

public void onCreate(Bundle
savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

personList = (ListView) findViewById(R.id.listView);

asyncQuery = new MyAsyncQueryHandler(getContentResolver());

}

@Override

protected void onResume()
{

super.onResume();

Uri uri = Uri.parse("content://com.android.contacts/data/phones");
// 联系人的Uri

String[] projection = { "_id","display_name","data1","sort_key" };//
查询的列

asyncQuery.startQuery(0, null,
uri, projection,null,null,

"sort_key COLLATE LOCALIZED
asc");// 按照sort_key升序查询

}

/**

* 数据库异步查询类AsyncQueryHandler

*

* @author administrator

*

*/

private class MyAsyncQueryHandlerextends AsyncQueryHandler
{

public MyAsyncQueryHandler(ContentResolver
cr) {

super(cr);

}

/**

* 查询结束的回调函数

*/

@Override

protected void onQueryComplete(int token,
Object cookie, Cursor cursor) {

if (cursor
!= null && cursor.getCount() >
0) {

List<ContentValues> list = new ArrayList<ContentValues>();

cursor.moveToFirst();

for (int i
= 0; i < cursor.getCount(); i++) {

ContentValues cv = new ContentValues();

cursor.moveToPosition(i);

String name = cursor.getString(1);

String number = cursor.getString(2);

String sortKey = cursor.getString(3);

if (number.startsWith("+86"))
{// 去除多余的中国地区号码标志,对这个程序没有影响。

cv.put(NAME, name);

cv.put(NUMBER, number.substring(3));

cv.put(SORT_KEY, sortKey);

} else {

cv.put(NAME, name);

cv.put(NUMBER, number);

cv.put(SORT_KEY, sortKey);

}

list.add(cv);

}

if (list.size()
> 0) {

setAdapter(list);

}

}

}

}

private void setAdapter(List<ContentValues>
list) {

adapter = new ListAdapter(this,
list);

personList.setAdapter(adapter);

}

private staticclass ViewHolder
{

TextView alpha;

TextView name;

TextView number;

}

/**

* 其他项目使用时,只需要传进来一个有序的list即可

*/

private class ListAdapterextends BaseAdapterimplements SectionIndexer
{

private LayoutInflater
inflater;

private List<ContentValues>
list;

private HashMap<String,
Integer> alphaIndexer;//保存每个索引在list中的位置【#-0,A-4,B-10】

private String[]
sections;//每个分组的索引表【A,B,C,F...】

public ListAdapter(Context
context, List<ContentValues> list) {

this.inflater
= LayoutInflater.from(context);

this.list
= list; // 该list是已经排序过的集合,有些项目中的数据必须要自己进行排序。

this.alphaIndexer
=new HashMap<String, Integer>();

for (int i
=0; i <list.size(); i++) {

String name = getAlpha(list.get(i).getAsString(SORT_KEY));

if(!alphaIndexer.containsKey(name)){//只记录在list中首次出现的位置

alphaIndexer.put(name, i);

}

}

Set<String> sectionLetters = alphaIndexer.keySet();

ArrayList<String> sectionList = new ArrayList<String>(

sectionLetters);

Collections.sort(sectionList);

sections = new String[sectionList.size()];

sectionList.toArray(sections);

}

@Override

public int getCount()
{

return list.size();

}

@Override

public Object
getItem(int position) {

return list.get(position);

}

@Override

public long getItemId(int position)
{

return position;

}

@Override

public View
getView(int position, View convertView,
ViewGroup parent) {

ViewHolder holder;

if (convertView
== null) {

convertView = inflater.inflate(R.layout.list_item,null);

holder = new ViewHolder();

holder.alpha = (TextView) convertView.findViewById(R.id.alpha);

holder.name = (TextView) convertView.findViewById(R.id.name);

holder.number = (TextView) convertView

.findViewById(R.id.number);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

ContentValues cv = list.get(position);

String name = cv.getAsString(NAME);

String number = cv.getAsString(NUMBER);

holder.name.setText(name);

holder.number.setText(number);

// 当前联系人的sortKey

String currentStr = getAlpha(list.get(position).getAsString(

SORT_KEY));

// 上一个联系人的sortKey

String previewStr = (position - 1) >= 0 ? getAlpha(list.get(

position - 1).getAsString(SORT_KEY)) : "
";

/**

* 判断显示#、A-Z的TextView隐藏与可见

*/

if (!previewStr.equals(currentStr))
{// 当前联系人的sortKey!=上一个联系人的sortKey,说明当前联系人是新组。

holder.alpha.setVisibility(View.VISIBLE);

holder.alpha.setText(currentStr);

} else {

holder.alpha.setVisibility(View.GONE);

}

return convertView;

}

/*

* 此方法根据联系人的首字母返回在list中的位置

*/

@Override

public int getPositionForSection(int section)
{

String later = sections[section];

return alphaIndexer.get(later);

}

/*

* 本例中可以不考虑这个方法

*/

@Override

public int getSectionForPosition(int position)
{

String key = getAlpha(list.get(position).getAsString(SORT_KEY));

for (int i
= 0; i < sections.length; i++) {

if (sections[i].equals(key))
{

return i;

}

}

return 0;

}

@Override

public Object[]
getSections() {

return sections;

}

}

/**

* 提取英文的首字母,非英文字母用#代替

*

* @param str

* @return

*/

private String
getAlpha(String str) {

if (str
== null) {

return "#";

}

if (str.trim().length()
== 0) {

return "#";

}

char c
= str.trim().substring(0, 1).charAt(0);

// 正则表达式,判断首字母是否是英文字母

Pattern pattern = Pattern.compile("^[A-Za-z]+{1}quot;);

if (pattern.matcher(c
+ "").matches()) {

return (c
+ "").toUpperCase(); //
大写输出

} else {

return "#";

}

}

}

2.布局文件

2.1.main.xml

[html] view
plaincopyprint?

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

<ListView

android:id="@+id/listView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:fastScrollEnabled="true"/>

</LinearLayout>

2.2.list_item.xml

[html] view
plaincopyprint?

<?xmlversion="1.0"encoding="utf-8"?>

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent">

<!-- 首字母 -->

<TextView

android:id="@+id/alpha"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="#333333"

android:paddingLeft="10dip"

android:textColor="#FFFFFF"

android:visibility="gone"/>

<!-- 联系人信息 -->

<ImageView

android:id="@+id/imageView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_below="@id/alpha"

android:src="@drawable/ic_launcher"/>

<TextView

android:id="@+id/name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignTop="@id/imageView"

android:layout_marginLeft="2.0dip"

android:layout_marginRight="5.0dip"

android:layout_marginTop="6.0dip"

android:layout_toRightOf="@id/imageView"

android:singleLine="true"

android:textAppearance="?android:textAppearanceMedium"/>

<TextView

android:id="@+id/number"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@id/name"

android:layout_alignWithParentIfMissing="true"

android:layout_below="@id/name"

android:ellipsize="marquee"

android:singleLine="true"

android:textAppearance="?android:textAppearanceSmall"/>

</RelativeLayout>

3.效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 联系人列表
相关文章推荐