android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)

android仿微信通讯录搜索示例(匹配拼音,字母,索引位置),第1张

概述前言:仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置

前言:

仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置

一:先看效果图

字母索引

搜索匹配

二:功能分析

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.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,index + 1);        }      }    }    return -1;  } 

最后附上源码https://github.com/youxiaochen/ContactList

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)全部内容,希望文章能够帮你解决android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1144467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存