温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

android如何实现仿微信通讯录搜索

发布时间:2021-06-28 09:46:31 来源:亿速云 阅读:189 作者:小新 栏目:移动开发

这篇文章将为大家详细讲解有关android如何实现仿微信通讯录搜索,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一:先看效果图

android如何实现仿微信通讯录搜索

字母索引

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;   }

关于“android如何实现仿微信通讯录搜索”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI