原始需求:
有联系人名字为‘张三’、‘张三丰’,搜索‘ZS’可以通过系统提供的Contacts.CONTENT_FILTER_URI搜索到。但是匹配字符串高亮时,无法智能将‘张三’高亮。
细化需求
- 需要将中文转换为拼音
- 提取拼音的首字母以及所对应原字符串的index
- 获取匹配首字母所对应原字符串的index
- 根据index高亮字符串
资源库
由于需要将汉字转换为拼音,因此需要引入谷歌ContactsProvider源码里的core-libart.jar包和里面的一个源代码类:HanziToPinyin.java。想用最新的可以在谷歌源码里找到。
要是报错:Conversion to Dalvik format failed with error 1
在项目中新建一个文件夹mylib,把core-libart.jar从libs中移动到新建的mylib中,并右键add to build path
代码
添加一个数据类,用来存储匹配成功的字符下标。
public class HighlightIndex {
public final int start;
public final int end;
public HighlightIndex(int start, int end) {
this.start = start;
this.end = end;
}
}
核心代码
先获取中文全拼,再提取出首字母成一个姓名缩写字符串,在通过关键字匹配姓名缩写,最后将匹配成功的字符对应上原始字符串的下标。
/** * 获取首字母缩略字符匹配的下标 * @param input 原字符串 * @param prefix 高亮字符串 * @return 原字符串需要高亮的下标位置(start和end)List * @author zhuxh2 * */
public static ArrayList<HighlightIndex> getAcronym(String input, String prefix) {
ArrayList<Token> tokens = HanziToPinyin.getInstance().getTokens(input);
//姓名缩写
StringBuilder acronym = new StringBuilder();
//缩写字母index
ArrayList<HighlightIndex> indexs = new ArrayList<HighlightIndex>();
//匹配后的缩写字母index
ArrayList<HighlightIndex> indexsResult = new ArrayList<HighlightIndex>();
int index = 0;
if (tokens != null && tokens.size() > 0) {
for (Token token : tokens) {
if (Token.PINYIN == token.type) {
acronym.append(token.target.charAt(0));
indexs.add(new HighlightIndex(index, index+1));
index++;
} else {
acronym.append(token.source.charAt(0));
indexs.add(new HighlightIndex(index, index+1));
index = index + token.source.length();
while(index < input.length() && input.charAt(index) == ' ')
index++;
}
}
int start = indexOfWordPrefix(acronym, prefix);
if(start != -1)
for(int j = start; j < start + prefix.length(); j++) {
indexsResult.add(indexs.get(j));
}
}
return indexsResult;
}
说一大堆没有直接来个源码干脆清晰
没有源码的技术博客不是好猿猴
附上源码