欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2017年09月15日 14:40:16   作者:游小陳  
本篇文章主要介紹了android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置),具有一定的參考價(jià)值,有興趣的可以了解一下

前言:

仿微信通訊錄搜索功能,通過漢字或拼音首字母找到匹配的聯(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í)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論