android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)
时间:2022-07-27
本文章向大家介绍android仿微信通讯录搜索示例(匹配拼音,字母,索引位置),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言:
仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置
一:先看效果图
字母索引
搜索匹配
二:功能分析
1:汉字转拼音
通讯录汉字转拼音(首个字符当考虑姓氏多音字), 现在转换拼音常见的有pinyin4j和tinypinyin, pinyin4j的功能强大,包含声调多音字,tinypinyin执行快占用内存少, 如果只是简单匹配通讯录,建议使用tinypinyin,用法也很简单这里不详细介绍
拼音类
public class CNPinyin <T extends CN implements Serializable, Comparable<CNPinyin<T {
/**
* 对应首字首拼音字母
*/
char firstChar;
/**
* 所有字符中的拼音首字母
*/
String firstChars;
/**
* 对应的所有字母拼音
*/
String[] pinyins;
/**
* 拼音总长度
*/
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实现StickyHeader效果,此效果很常见不详细介绍
3:根据转换好的拼音快速匹配
搜索匹配才是核心, 以下匹配原则,有优先顺序如果有匹配成功不执行后面的匹配原则
a:匹配原字符 并找出所匹配的起始位置与结束位置,如有中文匹配将不执行后面的拼音匹配原则
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:匹配单个字符拼音的首个字母(例如”游小陈”可以匹配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:所有字符拼音的匹配, 且第一个匹配位置的拼音必须一致(例如”游小陈 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()) {//首个位置索引
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) {//全拼匹配第一个必须在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;
}
/**
* 根据匹配字符递归查找下一结束位置
* @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()) {//首个位置索引
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) {//全拼匹配第一个必须在0位置
String left = matcher.replaceFirst("");
return end(pinyinGroup, left, index + 1);
}
}
}
return -1;
}
最后附上源码https://github.com/youxiaochen/ContactList
以上就是本文的全部内容,希望对大家的学习有所帮助。
- ttf设置文字字体
- R语言构建追涨杀跌量化交易模型(附源代码)
- Apache Spark中使用DataFrame的统计和数学函数
- android进程 清理及activity栈管理
- 机器学习模型的变量评估和选择基于技术指标『深度解析』
- Picasso and Android-Universal-Image-Loader缓存框架
- 解决ListView嵌套ListView遇到的问题
- 《OEA - 实体扩展属性系统 - 设计方案说明书》
- webview与js的相互交互
- Java与js的交互
- Rafy 框架 - 流水号插件
- 产品前端重构(TypeScript、MVC框架设计)
- 寻找最优持仓期的开盘缺口盈利交易策略基于Matlab
- Android SlidingMenu 侧拉菜单的使用(详细配置)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释