国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

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

2019-10-22 18:27:43
字體:
來源:轉載
供稿:網友

前言:

仿微信通訊錄搜索功能,通過漢字或拼音首字母找到匹配的聯系人并顯示匹配的位置

一:先看效果圖

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永春县| 雷山县| 巴马| 土默特左旗| 乐清市| 东阳市| 葫芦岛市| 永川市| 铁岭县| 祁东县| 揭西县| 通许县| 闽清县| 资兴市| 木里| 吉林市| 霞浦县| 时尚| 读书| 都匀市| 阿拉善左旗| 沂源县| 台南县| 邹城市| 缙云县| 山阴县| 游戏| 女性| 岐山县| 阳泉市| 额敏县| 商水县| 余江县| 红河县| 财经| 迭部县| 兰考县| 绥棱县| 祁东县| 祁东县| 德令哈市|