android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置)
前言:
仿微信通訊錄搜索功能,通過漢字或拼音首字母找到匹配的聯(lián)系人并顯示匹配的位置
一:先看效果圖

字母索引

搜索匹配
二:功能分析
1:漢字轉(zhuǎn)拼音
通訊錄漢字轉(zhuǎn)拼音(首個(gè)字符當(dāng)考慮姓氏多音字), 現(xiàn)在轉(zhuǎn)換拼音常見的有pinyin4j和tinypinyin, pinyin4j的功能強(qiáng)大,包含聲調(diào)多音字,tinypinyin執(zhí)行快占用內(nèi)存少, 如果只是簡(jiǎn)單匹配通訊錄,建議使用tinypinyin,用法也很簡(jiǎn)單這里不詳細(xì)介紹
拼音類
public class CNPinyin <T extends CN> implements Serializable, Comparable<CNPinyin<T>> {
/**
* 對(duì)應(yīng)首字首拼音字母
*/
char firstChar;
/**
* 所有字符中的拼音首字母
*/
String firstChars;
/**
* 對(duì)應(yīng)的所有字母拼音
*/
String[] pinyins;
/**
* 拼音總長(zhǎng)度
*/
int pinyinsTotalLength;
public final T data;
CNPinyin(T data) {
this.data = data;
}
public char getFirstChar() {
return firstChar;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder().append("--firstChar--").append(firstChar).append("--pinyins:");
for (String str : pinyins) {
sb.append(str);
}
return sb.toString();
}
int compareValue() {
if (firstChar == DEF_CHAR) {
return 'Z' + 1;
}
return firstChar;
}
@Override
public int compareTo(CNPinyin<T> tcnPinyin) {
int compare = compareValue() - tcnPinyin.compareValue();
if (compare == 0) {
String chinese1 = data.chinese();
String chinese2 = tcnPinyin.data.chinese();
return chinese1.compareTo(chinese2);
}
return compare;
}
}
2:定義索引欄 a~z,#控件
ItemDecoration配合RecyclerView實(shí)現(xiàn)StickyHeader效果,此效果很常見不詳細(xì)介紹
3:根據(jù)轉(zhuǎn)換好的拼音快速匹配
搜索匹配才是核心, 以下匹配原則,有優(yōu)先順序如果有匹配成功不執(zhí)行后面的匹配原則
a:匹配原字符 并找出所匹配的起始位置與結(jié)束位置,如有中文匹配將不執(zhí)行后面的拼音匹配原則
static CNPinyinIndex matcherChinese(CNPinyin cnPinyin, String keyword) {
if (keyword.length() < cnPinyin.data.chinese().length()) {
Matcher matcher = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE).matcher(cnPinyin.data.chinese());
if (matcher.find()) {
return new CNPinyinIndex(cnPinyin, matcher.start(), matcher.end());
}
}
return null;
}
b:匹配單個(gè)字符拼音的首個(gè)字母(例如"游小陳"可以匹配y, x, c, yx, xc, yxc)
static CNPinyinIndex matcherFirst(CNPinyin cnPinyin, String keyword) {
if (keyword.length() <= cnPinyin.pinyins.length) {
Matcher matcher = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE).matcher(cnPinyin.firstChars);
if (matcher.find()) {
return new CNPinyinIndex(cnPinyin, matcher.start(), matcher.end());
}
}
return null;
}
c:所有字符拼音的匹配, 且第一個(gè)匹配位置的拼音必須一致(例如"游小陳 youxiaochen", 必須匹配yo, you, xi, xia, xiao, ch, che, chen開頭等 例如 yo youx, youxi, youxiao, xiaoc, xiaoch, xiaochen等等)
/**
* 所有拼音匹配
* @param cnPinyin
* @param keyword
* @return
*/
static CNPinyinIndex matchersPinyins(CNPinyin cnPinyin, String keyword) {
if (keyword.length() > cnPinyin.pinyinsTotalLength) return null;
int start = -1;
int end = -1;
for (int i = 0; i < cnPinyin.pinyins.length; i++) {
String pat = cnPinyin.pinyins[i];
if (pat.length() >= keyword.length()) {//首個(gè)位置索引
Matcher matcher = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE).matcher(pat);
if (matcher.find() && matcher.start() == 0) {
start = i;
end = i + 1;
break;
}
} else {
Matcher matcher = Pattern.compile(pat, Pattern.CASE_INSENSITIVE).matcher(keyword);
if (matcher.find() && matcher.start() == 0) {//全拼匹配第一個(gè)必須在0位置
start = i;
String left = matcher.replaceFirst("");
end = end(cnPinyin.pinyins, left, ++i);
break;
}
}
}
if (start >= 0 && end >= start) {
return new CNPinyinIndex(cnPinyin, start, end);
}
return null;
}
/**
* 根據(jù)匹配字符遞歸查找下一結(jié)束位置
* @param pinyinGroup
* @param pattern
* @param index
* @return -1 匹配失敗
*/
private static int end(String[] pinyinGroup, String pattern, int index) {
if (index < pinyinGroup.length) {
String pinyin = pinyinGroup[index];
if (pinyin.length() >= pattern.length()) {//首個(gè)位置索引
Matcher matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(pinyin);
if (matcher.find() && matcher.start() == 0) {
return index + 1;
}
} else {
Matcher matcher = Pattern.compile(pinyin, Pattern.CASE_INSENSITIVE).matcher(pattern);
if (matcher.find() && matcher.start() == 0) {//全拼匹配第一個(gè)必須在0位置
String left = matcher.replaceFirst("");
return end(pinyinGroup, left, index + 1);
}
}
}
return -1;
}
最后附上源碼https://github.com/youxiaochen/ContactList
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用adb命令向Android模擬器中導(dǎo)入通訊錄聯(lián)系人的方法
- Android獲取手機(jī)通訊錄、sim卡聯(lián)系人及調(diào)用撥號(hào)界面方法
- Android通訊錄開發(fā)之刪除功能的實(shí)現(xiàn)方法
- Android個(gè)人手機(jī)通訊錄開發(fā)詳解
- Android實(shí)現(xiàn)通訊錄效果——獲取手機(jī)號(hào)碼和姓名
- Android讀取手機(jī)通訊錄聯(lián)系人到自己項(xiàng)目
- Android破解微信獲取聊天記錄和通訊錄信息(靜態(tài)方式)
- Android自定義View實(shí)現(xiàn)通訊錄字母索引(仿微信通訊錄)
- Android實(shí)現(xiàn)仿通訊錄側(cè)邊欄滑動(dòng)SiderBar效果代碼
- Android Studio實(shí)現(xiàn)簡(jiǎn)單的通訊錄
相關(guān)文章
android 獲取APP的唯一標(biāo)識(shí)applicationId的實(shí)例
下面小編就為大家分享一篇android 獲取APP的唯一標(biāo)識(shí)applicationId的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2018-02-02
Android 通過Base64上傳圖片到服務(wù)器實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了Android 通過Base64上傳圖片到服務(wù)器實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能【附完整demo源碼下載】
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能,結(jié)合實(shí)例形式分析了Android計(jì)算器的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,并附帶完整demo源碼供讀者下載參考,需要的朋友可以參考下2017-11-11
Android列表實(shí)現(xiàn)(2)_游標(biāo)列表案例講解
最近開始學(xué)習(xí)android的ui 游標(biāo)列表實(shí)現(xiàn),先上幾個(gè)相關(guān)的例子,后續(xù)還會(huì)有更新,感興趣的朋友可以研究下2012-12-12
Android ListView獲得選項(xiàng)中的值
本篇文章主要介紹Android ListView,在Android開發(fā)過程中經(jīng)常會(huì)用到ListView 組件并有監(jiān)聽事件,這里給大家一個(gè)簡(jiǎn)單實(shí)例,來(lái)說(shuō)明如何得到ListView選項(xiàng)中的值2016-07-07
Android 和 windows C/C++/QT通訊時(shí)字節(jié)存儲(chǔ)
本篇文章主要介紹 Android和Windows 通訊時(shí)數(shù)據(jù)地址的理解,這里提供代碼實(shí)例進(jìn)行分析,有需要參考的朋友可以看下2016-07-07
Android自定義ProgressBar實(shí)現(xiàn)漂亮的進(jìn)度提示框
這篇文章主要為大家詳細(xì)介紹了Android自定義ProgressBar實(shí)現(xiàn)漂亮的進(jìn)度提示框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
Android開發(fā)筆記SQLite優(yōu)化記住密碼功能
這篇文章主要為大家詳細(xì)介紹了Android開發(fā)筆記SQLite優(yōu)化記住密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Android studio 廣播的簡(jiǎn)單使用代碼詳解
這篇文章主要介紹了Android studio 廣播的簡(jiǎn)單使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果(一)
這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)動(dòng)畫效果的第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08

