想知道效果自己先看下手机或者模拟器的联系人,字母分类栏的推动效果。
C栏目把B推上去.
package com.lee.contact;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.TextView;
/**
* 申明一下,目前没有对联系人中文进行拼音转换 只能用于英文联系人,所以中文就别测试了,肯定出问题的。 转拼音网上有资源,自己下载,我的C库是公司的就不开源了
*
* @author leehom
*
*/
public class MContactActivity extends Activity implements OnScrollListener {
private ListView listView;
// private EditText input;
private String key;
private Collator cmp = Collator.getInstance(java.util.Locale.CHINA);
private ArrayList<ContactItem> srcAll = new ArrayList<ContactItem>();
// private Vibrator vibrator;
private MoveLayout board;
private TextView name;
private MoveLayout move_board;
private TextView move_name;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// deleteAll();// 最好在模拟器上测试,不然联系人全部删除光了
// generater(1000);// 添加1000联系人
// vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
setContentView(R.layout.friend_list);
listView = (ListView) findViewById(R.id.list);
board = (MoveLayout) findViewById(R.id.board);
board.setBackgroundColor(0xFF333333);
name = (TextView) board.findViewById(R.id.name);
move_board = (MoveLayout) findViewById(R.id.move_board);
move_board.setBackgroundColor(0xFF333333);
move_name = (TextView) move_board.findViewById(R.id.move_name);
listView.setOnScrollListener(this);
// listView.setOnItemLongClickListener(new OnItemLongClickListener() {
//
// @Override
// public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
// int position, long arg3) {
// // TODO Auto-generated method stub
// vibrator.vibrate(50);
// return false;
// }
// });
// input = (EditText) findViewById(R.id.input);
// input.addTextChangedListener(new TextWatcher() {
//
// @Override
// public void onTextChanged(CharSequence s, int start, int before,
// int count) {
// // TODO Auto-generated method stub
//
// }
//
// @Override
// public void beforeTextChanged(CharSequence s, int start, int count,
// int after) {
// // TODO Auto-generated method stub
//
// }
//
// @Override
// public void afterTextChanged(Editable s) {
// // TODO Auto-generated method stub
// key = s.toString();
// // handler.sendEmptyMessage(0);
// }
// });
// input.requestFocus();
// long begin = System.currentTimeMillis();
getContacts();
// long use = System.currentTimeMillis() - begin;
}
// public Handler handler = new Handler() {
//
// @Override
// public void handleMessage(Message msg) {
// // TODO Auto-generated method stub
// check();
// }
//
// };
public void check() {
ArrayList<ContactItem> list = new ArrayList<ContactItem>();
for (int i = 0; i < srcAll.size(); i++) {
ContactItem info = (ContactItem) srcAll.get(i).clone();
int ch;
if ((ch = info.name.toLowerCase().indexOf(key.toLowerCase())) != -1) {
StringBuffer html = new StringBuffer();
html.append(info.name.substring(0, ch));
html.append("<font color=#00FF00>");
html.append(info.name.substring(ch, ch + key.length()));
html.append("</font>");
html.append(info.name.substring(ch + key.length(),
info.name.length()));
info.html = html.toString();
list.add(info);
}
}
adapter.setList(list);
listView.setAdapter(adapter);
}
// 查询联系人
private void getContacts() {
Hashtable<String, ContactItem> map = new Hashtable<String, ContactItem>();
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
int index = 0;
// 循环遍历
if (cursor.moveToFirst()) {
do {
ContactItem info = new ContactItem();
// 获得联系人的ID号
info.contactId = cursor.getString(cursor
.getColumnIndex(BaseColumns._ID));
// 获得联系人姓名
info.name = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// 获得联系人号码数
info.phoneCount = cursor
.getInt(cursor
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (info.phoneCount > 0) {
if (++index % 5 == 0)
info.changeToVideo();
else if (index % 9 == 0)
info.changeToMsg(index);
else if (index % 13 == 0)
info.changeToTalk();
map.put(info.contactId, info);
}
} while (cursor.moveToNext());
}
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
// 循环遍历
if (phones.moveToFirst()) {
do {
String id = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String num = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (map.containsKey(id)) {
ContactItem info = map.get(id);
info.num = num;
}
} while (phones.moveToNext());
}
Cursor email = getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, null,
null, null);
if (email.moveToFirst()) {
do {
String id = email
.getString(email
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String eml = email
.getString(email
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
if (map.containsKey(id)) {
ContactItem info = map.get(id);
info.email = eml;
}
} while (email.moveToNext());
}
Enumeration<String> keys = map.keys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
srcAll.add(map.get(key));
}
Collections.sort(srcAll, new Comparator<ContactItem>() {
@Override
public int compare(ContactItem r1, ContactItem r2) {
return cmp.compare(r1.name, r2.name);
}
});
adapter = new ContactAdapter(this, srcAll);
listView.setAdapter(adapter);
}
private ContactAdapter adapter;
private static final String[] PHONES_PROJECTION = new String[] {
Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID, Phone.CONTACT_ID };
/** 联系人显示名称 **/
public static final int PHONES_DISPLAY_NAME_INDEX = 0;
/** 电话号码 **/
public static final int PHONES_NUMBER_INDEX = 1;
/** 得到手机SIM卡联系人人信息 **/
public void getSIMContacts() {
ContentResolver resolver = getContentResolver();
// 获取Sims卡联系人
Uri uri = Uri.parse("content://icc/adn");
Cursor phoneCursor = resolver.query(uri, PHONES_PROJECTION, null, null,
null);
if (phoneCursor != null) {
while (phoneCursor.moveToNext()) {
// 得到手机号码
String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
// 当手机号码为空的或者为空字段 跳过当前循环
if (TextUtils.isEmpty(phoneNumber))
continue;
// // 得到联系人名称
// String contactName = phoneCursor
// .getString(PHONES_DISPLAY_NAME_INDEX);
// Sim卡中没有联系人头像
}
phoneCursor.close();
}
}
public void generater(int num) {
Random random = new Random();
ArrayList<String> list = new ArrayList<String>();
InputStream is = getResources().openRawResource(R.raw.name);
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(is, "GBK"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
String line = null;
while ((line = reader.readLine()) != null) {
int ch = line.indexOf(",");
if (ch != -1)
list.add(line.substring(0, ch));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int min = num < list.size() ? num : list.size();
for (int i = 0; i < list.size() && i < num; i++) {
// String name = str.substring(rand, rand + random.nextInt(2) + 2);
String name = list.get(i);
String phone = "186" + String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10))
+ String.valueOf(random.nextInt(10));
System.out.println("left:" + min--);
insertContact(name, phone);
}
}
public void insertContact(String name, String phone) {
ContentValues values = new ContentValues();
// insert a null value
Uri rawContactUri = getContentResolver().insert(
RawContacts.CONTENT_URI, values);
long rawContactsId = ContentUris.parseId(rawContactUri);
// 往刚才的空记录中插入姓名
values.clear();
values.put(StructuredName.RAW_CONTACT_ID, rawContactsId);
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
values.put(StructuredName.DISPLAY_NAME, name);
getContentResolver().insert(Data.CONTENT_URI, values);
// 插入电话
values.clear();
values.put(Phone.RAW_CONTACT_ID, rawContactsId);
values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
values.put(Phone.NUMBER, phone);
getContentResolver().insert(Data.CONTENT_URI, values);
}
public void deleteAll() {
getContentResolver().delete(ContactsContract.Data.CONTENT_URI, null,
null);
getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI,
null, null);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
View mView = view.getChildAt(1);
if (adapter != null && visibleItemCount + 1 < adapter.getCount()) {
ContactItem item = adapter.getItem(firstVisibleItem + 1);
if (adapter.getItem(firstVisibleItem).isTotalHead) {
move_board.setVisibility(View.GONE);
board.setVisibility(View.GONE);
} else if (item.isHead) {
move_board.setVisibility(View.VISIBLE);
int vY = mView.getTop();
if (board.getInit_height() >= vY) {
// 重叠
board.setVisibility(View.GONE);
move_board.move(vY - board.getInit_height());
char c = adapter.getItem(firstVisibleItem).name.charAt(0);
String s = String.valueOf(c);
move_name.setText(s);
} else {
// 没有重叠显示,重置为0
move_board.move(0);
}
} else {
char c = item.name.charAt(0);
String s = String.valueOf(c);
name.setText(s);
// 不是分组显示
board.setVisibility(View.VISIBLE);
}
}
}
}
package com.lee.contact;
import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public class MoveLayout extends LinearLayout {
private int init_height;
public MoveLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
init_height = b - t;
}
public int getInit_height() {
return init_height;
}
public void move(int value) {
new AsynMove().execute(new Integer[] { value });
}
private class AsynMove extends AsyncTask<Integer, Integer, Void> {
@Override
protected Void doInBackground(Integer... params) {
// TODO Auto-generated method stub
publishProgress(params);
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
lp.topMargin = values[0];
setLayoutParams(lp);
}
}
}
package com.lee.contact;
import java.io.Serializable;
public class ContactItem implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
private static final String serverIP = "@audivi.com";
public static final byte MESSAGE = 1;
public static final byte VIDEO = 2;
public static final byte TALK = 3;
public static final byte OFF_LINE = 4;
public static final byte ON_LINE = 5;
protected String contactId;
protected String name;
protected String html;
protected String email;
protected String num;
protected int phoneCount;
protected int msgCount;
protected byte status;
protected boolean isHead;
protected boolean isTotalHead;
@Override
protected Object clone() {
// TODO Auto-generated method stub
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 更新用户消息条目
* @param msgCount
* 消息条目
*/
public void changeToMsg(int msgCount) {
status = MESSAGE;
this.msgCount = msgCount;
}
/**
* 切换到视频状态
*/
public void changeToVideo() {
status = VIDEO;
}
/**
* 切换到语音状态
*/
public void changeToTalk() {
status = TALK;
}
public String getSipUri() {
if (num != null)
return num.replace("@", ".") + serverIP;
else
return email.replace("@", ".") + serverIP;
}
}
package com.lee.contact;
import java.util.ArrayList;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ContactAdapter extends BaseAdapter {
protected ArrayList<ContactItem> list;
protected Context context;
protected LayoutInflater inflater;
public ContactAdapter(Context context, ArrayList<ContactItem> list) {
// TODO Auto-generated constructor stub
ArrayList<ContactItem> newList = new ArrayList<ContactItem>();
for (int i = 0; i < list.size(); i++) {
ContactItem item = list.get(i);
char fc = item.name.charAt(0);
if (i + 1 < list.size()) {
char temp = list.get(i + 1).name.charAt(0);
if (i == 0) {
ContactItem ci = new ContactItem();
ci.name = "显示" + list.size() + "位联系人";
ci.isHead = true;
ci.isTotalHead = true;
newList.add(ci);
ci = new ContactItem();
ci.name = String.valueOf('A');
ci.isHead = true;
newList.add(ci);
newList.add(item);
} else if (fc != temp) {
ContactItem ci = new ContactItem();
ci.name = String.valueOf((char) (fc + 1));
ci.isHead = true;
newList.add(item);
newList.add(ci);
} else {
newList.add(item);
}
}
}
this.list = newList;
this.context = context;
inflater = LayoutInflater.from(context);
}
public void setList(ArrayList<ContactItem> list) {
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public ContactItem getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = null;
if (convertView != null) {
view = convertView;
} else {
LinearLayout layout = (LinearLayout) inflater.inflate(
R.layout.chat_contact_item, parent, false);
view = layout;
}
TextView name = (TextView) view.findViewById(R.id.name);
// ImageView status = (ImageView) view.findViewById(R.id.status);
ContactItem info = getItem(position);
if (info.email != null)
name.setText(Html.fromHtml((info.html == null ? info.name
: info.html) + "(" + info.email + ")"));
else
name.setText(Html.fromHtml((info.html == null ? info.name
: info.html)));
ImageView head = (ImageView) view.findViewById(R.id.head);
if (info.isHead) {
view.setBackgroundColor(0xFF333333);
head.setVisibility(View.GONE);
} else {
view.setBackgroundColor(0x0);
head.setVisibility(View.VISIBLE);
}
// switch (info.status) {
// case ContactItem.MESSAGE:
// status.setBackgroundResource(R.drawable.chat_contact_message);
// break;
// case ContactItem.VIDEO:
// status.setBackgroundResource(R.drawable.chat_contact_video);
// break;
// case ContactItem.TALK:
// status.setBackgroundResource(R.drawable.chat_contact_stop);
// break;
// default:
// status.setBackgroundDrawable(null);
// break;
// }
// TextView msgCount = (TextView) view.findViewById(R.id.msgcount);
// msgCount.setVisibility(View.GONE);
// if (info.msgCount > 0) {
// msgCount.setText(String.valueOf(info.msgCount));
// msgCount.setVisibility(View.VISIBLE);
// }
return view;
}
}
工程项目下载: http://download.csdn.net/detail/lh15871815717/3896391