需求:
launcher 抽屉界面搜索功能实现模糊查询,中文、英文字符串里面只要出现查询输入的字符串就会被查询到
效果 :
要实现输入字母查询到中文的应用,就需要将中文应用的title转换成拼音,这里使用pinyin4j-2.5.0.jar来实现 ,如下官方下载链接
https://sourceforge.net/projects/pinyin4j/files/https://sourceforge.net/projects/pinyin4j/files/
项目导入pinyin4j-2.5.0.jar,在项目libs目录下添加jar包即可(app/libs/pinyin4j-2.5.0.jar)。
然后在build.gradle 的dependencies下面导入jar包:
dependencies {
...
implementation files('libs/pinyin4j-2.5.0.jar')
...
}
在项目的Util类下面写一个汉字转为拼音的ChineseCharacterToPinyin静态方法:
/**
* 汉字转为拼音
* @param chinese
* @return
*/
public static String ChineseCharacterToPinyin(String chinese){
String pinyinStr = "";
char[] newChar = chinese.toCharArray();
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
for (int i = 0; i < newChar.length; i++) {
if (newChar[i] > 128) {
try {
pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
}else{
pinyinStr += newChar[i];
}
}
return pinyinStr;
}
launcher3搜索算法相关的逻辑在DefaultAppSearchAlgorithm.java的getTitleMatchResult方法下面,其中matches方法返回true就表示可以查询到。
app/src/main/java/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
其中contains() 方法用于判断字符串中是否包含指定的字符或字符串。
如果包含指定的字符或字符串返回 true,否则返回 false。
private ArrayList<ComponentKey> getTitleMatchResult(String query) {
// Do an intersection of the words in the query and each title, and filter out all the
// apps that don't match all of the words in the query.
final String queryTextLower = query.toLowerCase();
final ArrayList<ComponentKey> result = new ArrayList<>();
StringMatcher matcher = StringMatcher.getInstance();
for (AppInfo info : mApps) {
if (matches(info, queryTextLower, matcher)) {
result.add(info.toComponentKey());
}
}
return result;
}
public static boolean matches(AppInfo info, String query, StringMatcher matcher) {
int queryLength = query.length();
String title = info.title.toString();
int titleLength = title.length();
if (titleLength < queryLength || queryLength <= 0) {
return false;
}
+ String pinyin = Utilities.ChineseCharacterToPinyin(title);
+ if (title.contains(query) || pinyin.contains(query) ) return true;
int lastType;
int thisType = Character.UNASSIGNED;
int nextType = Character.getType(title.codePointAt(0));
int end = titleLength - queryLength;
for (int i = 0; i <= end; i++) {
lastType = thisType;
thisType = nextType;
nextType = i < (titleLength - 1) ?
Character.getType(title.codePointAt(i + 1)) : Character.UNASSIGNED;
if (isBreak(thisType, lastType, nextType) &&
matcher.matches(query, title.substring(i, i + queryLength))) {
return true;
}
}
return false;
}
完成。