編輯:關於Android編程
公司最近的項目中遇到一個需求需要讀取通訊錄聯系人,並需要支持對聯系人的模糊查詢及批量選取,網上找了好幾個例子,模糊查詢這塊處理的都有點小瑕疵,最終自己在各位網友的辛勤貢獻基礎之上進行了優化,最終做出了聯系人模糊查詢. 支持以下功能:
1.按 號碼 , 姓名 , 首字母簡拼 , 全拼 模糊查詢


package com.xbc.utils.activity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.xbc.contacts.R;
import com.xbc.utils.activity.ContactsSortAdapter.ViewHolder;
import com.xbc.utils.activity.SideBar.OnTouchingLetterChangedListener;
public class ContactsActivity extends Activity {
ListView mListView;
EditText etSearch;
ImageView ivClearText;
private SideBar sideBar;
private TextView dialog;
private List mAllContactsList;
private ContactsSortAdapter adapter;
/**
* 漢字轉換成拼音的類
*/
private CharacterParser characterParser;
/**
* 根據拼音來排列ListView裡面的數據類
*/
private PinyinComparator pinyinComparator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_contacts);
init();
}
private void init() {
initView();
initListener();
loadContacts();
}
private void initListener() {
/**清除輸入字符**/
ivClearText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
etSearch.setText();
}
});
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void afterTextChanged(Editable e) {
String content = etSearch.getText().toString();
if (.equals(content)) {
ivClearText.setVisibility(View.INVISIBLE);
} else {
ivClearText.setVisibility(View.VISIBLE);
}
if (content.length() > 0) {
ArrayList fileterList = (ArrayList) search(content);
adapter.updateListView(fileterList);
//mAdapter.updateData(mContacts);
} else {
adapter.updateListView(mAllContactsList);
}
mListView.setSelection(0);
}
});
//設置右側[A-Z]快速導航欄觸摸監聽
sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {
@Override
public void onTouchingLetterChanged(String s) {
//該字母首次出現的位置
int position = adapter.getPositionForSection(s.charAt(0));
if (position != -1) {
mListView.setSelection(position);
}
}
});
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView adapterView, View view, int position, long arg3) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.cbChecked.performClick();
adapter.toggleChecked(position);
}
});
}
private void initView() {
sideBar = (SideBar) findViewById(R.id.sidrbar);
dialog = (TextView) findViewById(R.id.dialog);
sideBar.setTextView(dialog);
ivClearText = (ImageView) findViewById(R.id.ivClearText);
etSearch = (EditText) findViewById(R.id.et_search);
mListView = (ListView) findViewById(R.id.lv_contacts);
/** 給ListView設置adapter **/
characterParser = CharacterParser.getInstance();
mAllContactsList = new ArrayList();
pinyinComparator = new PinyinComparator();
Collections.sort(mAllContactsList, pinyinComparator);// 根據a-z進行排序源數據
adapter = new ContactsSortAdapter(this, mAllContactsList);
mListView.setAdapter(adapter);
}
private void loadContacts() {
new Thread(new Runnable() {
@Override
public void run() {
try {
ContentResolver resolver = getApplicationContext().getContentResolver();
Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, new String[] { Phone.DISPLAY_NAME, Phone.NUMBER, sort_key }, null, null, sort_key COLLATE LOCALIZED ASC);
if (phoneCursor == null || phoneCursor.getCount() == 0) {
Toast.makeText(getApplicationContext(), 未獲得讀取聯系人權限 或 未獲得聯系人數據, Toast.LENGTH_SHORT).show();
return;
}
int PHONES_NUMBER_INDEX = phoneCursor.getColumnIndex(Phone.NUMBER);
int PHONES_DISPLAY_NAME_INDEX = phoneCursor.getColumnIndex(Phone.DISPLAY_NAME);
int SORT_KEY_INDEX = phoneCursor.getColumnIndex(sort_key);
if (phoneCursor.getCount() > 0) {
mAllContactsList = new ArrayList();
while (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
if (TextUtils.isEmpty(phoneNumber))
continue;
String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);
String sortKey = phoneCursor.getString(SORT_KEY_INDEX);
//System.out.println(sortKey);
SortModel sortModel = new SortModel(contactName, phoneNumber, sortKey);
//優先使用系統sortkey取,取不到再使用工具取
String sortLetters = getSortLetterBySortKey(sortKey);
if (sortLetters == null) {
sortLetters = getSortLetter(contactName);
}
sortModel.sortLetters = sortLetters;
sortModel.sortToken = parseSortKey(sortKey);
mAllContactsList.add(sortModel);
}
}
phoneCursor.close();
runOnUiThread(new Runnable() {
public void run() {
Collections.sort(mAllContactsList, pinyinComparator);
adapter.updateListView(mAllContactsList);
}
});
} catch (Exception e) {
Log.e(xbc, e.getLocalizedMessage());
}
}
}).start();
}
/**
* 名字轉拼音,取首字母
* @param name
* @return
*/
private String getSortLetter(String name) {
String letter = #;
if (name == null) {
return letter;
}
//漢字轉換成拼音
String pinyin = characterParser.getSelling(name);
String sortString = pinyin.substring(0, 1).toUpperCase(Locale.CHINESE);
// 正則表達式,判斷首字母是否是英文字母
if (sortString.matches([A-Z])) {
letter = sortString.toUpperCase(Locale.CHINESE);
}
return letter;
}
/**
* 取sort_key的首字母
* @param sortKey
* @return
*/
private String getSortLetterBySortKey(String sortKey) {
if (sortKey == null || .equals(sortKey.trim())) {
return null;
}
String letter = #;
//漢字轉換成拼音
String sortString = sortKey.trim().substring(0, 1).toUpperCase(Locale.CHINESE);
// 正則表達式,判斷首字母是否是英文字母
if (sortString.matches([A-Z])) {
letter = sortString.toUpperCase(Locale.CHINESE);
}
return letter;
}
/**
* 模糊查詢
* @param str
* @return
*/
private List search(String str) {
List filterList = new ArrayList();//過濾後的list
if (str.matches(^([0-9]|[/+])*$)) {//正則表達式 匹配號碼
for (SortModel contact : mAllContactsList) {
if (contact.number != null && contact.name != null) {
if (contact.number.contains(str) || contact.name.contains(str)) {
if (!filterList.contains(contact)) {
filterList.add(contact);
}
}
}
}
} else {
for (SortModel contact : mAllContactsList) {
if (contact.number != null && contact.name != null) {
//姓名全匹配,姓名首字母簡拼匹配,姓名全字母匹配
if (contact.name.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))
|| contact.sortKey.toLowerCase(Locale.CHINESE).replace( , ).contains(str.toLowerCase(Locale.CHINESE))
|| contact.sortToken.simpleSpell.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))
|| contact.sortToken.wholeSpell.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))) {
if (!filterList.contains(contact)) {
filterList.add(contact);
}
}
}
}
}
return filterList;
}
String chReg = [\u4E00-\u9FA5]+;//中文字符串匹配
//String chReg=[^\u4E00-\u9FA5];//除中文外的字符匹配
/**
* 解析sort_key,封裝簡拼,全拼
* @param sortKey
* @return
*/
public SortToken parseSortKey(String sortKey) {
SortToken token = new SortToken();
if (sortKey != null && sortKey.length() > 0) {
//其中包含的中文字符
String[] enStrs = sortKey.replace( , ).split(chReg);
for (int i = 0, length = enStrs.length; i < length; i++) {
if (enStrs[i].length() > 0) {
//拼接簡拼
token.simpleSpell += enStrs[i].charAt(0);
token.wholeSpell += enStrs[i];
}
}
}
return token;
}
}
Android ListFragment
Android是在Android 3.0(API level 11)開始引入Fragment的(為了兼容較低版本的設備使用支持庫類)。可以把Fragment看
Buzz桌面教程-更換桌面壁紙
Buzz桌面換壁紙方法 1.雙指下滑打開Buzz主菜單,選擇“壁紙”。2.然後從“多項壁紙”&ld
靠譜助手微信/陌陌怎麼定位
有很多朋友會在電腦上用靠譜助手安裝微信/陌陌等,但是電腦沒有GPS定位,那麼微信/陌陌要怎麼定位呢?裝個軟件就可以搞定了,跟我一起來操作。靠譜助
Android_GestureDetector手勢滑動使用
Gesture在 ViewGroup中使用GestureDetector類可以讓我們快速的處理手勢事件,如點擊,滑動等。使用GestureDetector分三步:1. 定