作為一個(gè)拿來主義者,最開始當(dāng)然要在網(wǎng)上尋找一番,找個(gè)Util省的自己寫了。
很快,就找到了一個(gè)......
public class PartColorTextView extends TextView {
private final String SRM = "<font color=\"⊙\">%1$s</font>";//文字轉(zhuǎn)換Hmtl的格式固定不要?jiǎng)? private final String OF = "⊙";//替換顏色的字符
public PartColorTextView(Context context) {
super(context);
}
public PartColorTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PartColorTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* @author WangHan
* 創(chuàng)建時(shí)間:2016/11/2 14:38
* 方法名:setPartText
* 描述: 給文字顏色設(shè)置
* 參數(shù):allText:全部文字 keyText:變色關(guān)鍵字 otherTextColor:默認(rèn)文字顏色 keyTextColor:要變顏色的字的顏色必須是個(gè)Color(getRe.getColor.)這樣獲得
* 返回值:
* 特殊注釋:該方法適合只有一個(gè)關(guān)鍵詞的時(shí)候
*/
public void setPartText(String allText, String keyText, int otherTextColor, int keyTextColor) {
String NF = String.format("#%06X", 0xFFFFFF & keyTextColor);
String replace = SRM.replace(OF, NF);
String format = String.format(replace, keyText);
try {
String textStr = allText.replaceAll(keyText, format);
Spanned spanned = Html.fromHtml(textStr);
setTextColor(otherTextColor);
setText(spanned);
} catch (PatternSyntaxException e) {
e.printStackTrace();
}
}
/**
* @author WangHan
* 創(chuàng)建時(shí)間:2016/11/2 14:38
* 方法名:setPartText
* 描述: 給文字顏色設(shè)置
* 參數(shù):allText:全部文字 keyColorMap:用于一段話有多個(gè),且顏色要求不同的集合,Key是關(guān)鍵字,Value是Color keyTextColor:要變顏色的字的顏色必須是個(gè)Color(getRe.getColor.)這樣獲得
* 返回值:
* 特殊注釋:該方法適合一段話有多個(gè)關(guān)鍵詞的時(shí)候
*/
public void setPartText(String allText, HashMap<String, Integer> keyColorMap, int otherTextColor) {
Spanned spanned = null;
String textStr = null;
Set<String> keySet = null;
keySet = keyColorMap.keySet();
for (String s : keySet) {
String NF = String.format("#%06X", 0xFFFFFF & keyColorMap.get(s));
String replace = SRM.replace(OF, NF);
String format = String.format(replace, s);
try {
if (textStr == null) {
textStr = allText.replaceAll(s, format);
} else {
textStr = textStr.replaceAll(s, format);
}
} catch (PatternSyntaxException e) {
e.printStackTrace();
}
}
setTextColor(otherTextColor);
spanned = Html.fromHtml(textStr);
setText(spanned);
}
}
通過加html標(biāo)簽來改變樣式,不過在對(duì)比數(shù)據(jù)的時(shí)候發(fā)現(xiàn)了BUG。比如,文章中有“小學(xué)生”三個(gè)字,關(guān)鍵詞是“小學(xué)”、“學(xué)生”(實(shí)際中是類似的其他詞),而我只標(biāo)紅了“學(xué)生”。
想了想知道了原因,我在遍歷查找“小學(xué)”的時(shí)候如果找到了就給“小學(xué)”包了一個(gè)<font color=""></font>標(biāo)簽,那接下來遍歷查找“學(xué)生”的時(shí)候由于中間有標(biāo)簽隔著自然是不會(huì)被標(biāo)紅。
不對(duì)啊,那應(yīng)該標(biāo)紅的是“小學(xué)”結(jié)果怎么是“學(xué)生”呢??
原來這里使用的是HashMap, keyColorMap.keySet()得到的key的集合是無序的,也就是我第一個(gè)查找的是“學(xué)生”關(guān)鍵字,換成LinkedfHashMap就可以了,LinkedfHashMap是HashMap的子類,得到的是有序的。
那怎么解決將“小學(xué)生”都標(biāo)紅呢?
利用textview的復(fù)合文本。
public static SpannableString matcherSearchTitle(String text,
LinkedHashMap<String,Integer> map) {
Set<String> keySet = map.keySet();
SpannableString s = new SpannableString(text);
for (String key : keySet) {
Pattern p = Pattern.compile(key);
Matcher m = p.matcher(s);
while (m.find()) {
int start = m.start();
int end = m.end();
s.setSpan(new ForegroundColorSpan(map.get(key)), start, end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return s;
}
返回值直接利用textView.setText()就可以了簡(jiǎn)單好用,后來又發(fā)現(xiàn)一個(gè)問題......
如果文章中有“哈哈哈哈哈”,關(guān)鍵詞是“哈哈哈”,是不是需要將“哈哈哈哈哈”全部標(biāo)紅,結(jié)果卻是只標(biāo)紅了前三個(gè)“哈”。
不用想,那一定是API查找的方式是找到“哈哈哈”標(biāo)紅之后從第四個(gè)“哈”查找的,所以最后兩個(gè)“哈”必然不滿足“哈哈哈”關(guān)鍵詞的要求。
因此,想要全部標(biāo)紅那我就挨個(gè)字去遍歷即可。
public static SpannableString matcherSearchTitle(String text,
LinkedHashMap<String,Integer> map) {
Set<String> keySet = map.keySet();
SpannableString s = new SpannableString(text);
for (String key : keySet) {
int a = text.indexOf(key);//*第一個(gè)出現(xiàn)的索引位置
while (a != -1) {
s.setSpan(new ForegroundColorSpan(map.get(key)), a, a+key.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
a = text.indexOf(key, a + 1);//*從這個(gè)索引往后開始第一個(gè)出現(xiàn)的位置
}
}
return s;
}
這個(gè)遍歷方式就可以一個(gè)字一個(gè)字的去遍歷。
最后,我們也不擔(dān)心順序問題了,可以將LinkedHashMap改回HashMap,畢竟HashMap效率高一些。