最近杭研院的stone app有接入搜索引擎的頁面歇父。當(dāng)用戶輸入關(guān)鍵字時坏怪,搜索引擎返回匹配的結(jié)果。匹配的結(jié)果里的對應(yīng)關(guān)鍵字做高亮顯示积糯。如下圖所示
服務(wù)器點返回的結(jié)果為帶標(biāo)簽的字符串掂墓。比如,搜索"故人"關(guān)鍵字,返回的字符串如下
等閑變卻<gaoliang>故人</gaoling>心看成,卻道<gaoliang>故人</gaoliang>心易變君编。
客戶端需要識別被高亮的字符串,并予以高亮顯示川慌。代碼如下:
/**
* 將left和right標(biāo)注的文本高亮出來吃嘿,高亮
*@param text
*@param left
*@param right
*@return
*/
public SpannableString highlightStr(String text,String left,String right){
if(text ==null){
return null;
}
if(text.trim().length() ==0){
return null;
}
if(left ==null|| left.trim().length() ==0){
return null;
}
if(right ==null|| right.trim().length() ==0){
return null;
}
int leftLen = left.length();
int rightLen = right.length();
int totalLen = leftLen + rightLen;
if(text.trim().length() <= totalLen){
return new SpannableString(text);
}
StringBuffer textNew =new StringBuffer(text);
int pivot =0;
int length = text.length();
Map pairs =new HashMap();
Map newPairs =new HashMap();
int times =0;
while(pivot != length -1){
int leftIndex = text.indexOf(left,pivot);
if(leftIndex != -1){
int newLeftIndex = leftIndex - totalLen*times;
textNew.delete(newLeftIndex, newLeftIndex+leftLen);
int rightIndex = text.indexOf(right,leftIndex);
if(rightIndex != -1){
int newRightIndex = rightIndex - totalLen*(times+1)+rightLen;
textNew.delete(newRightIndex, newRightIndex+rightLen);
times++;
pairs.put(leftIndex,rightIndex );
newPairs.put(newLeftIndex, newRightIndex);
pivot = rightIndex;
}else{
pivot = leftIndex;
}
}
pivot++;
}
SpannableString sp =new SpannableString(textNew);
for(Map.Entry entry:newPairs.entrySet()) {
Integer start = entry.getKey();
Integer end = entry.getValue();
sp.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
return sp;
}
算法要點:
1、拷貝text為newText梦重。
2兑燥、在text中掃描left,如果含有l(wèi)eft琴拧,則掃描right降瞳。記錄下leftIndex,rightIndex。
3挣饥、記錄newLeftIndex與newRightIndex除师。記錄到newPairs中。
//totalLen=leftLen+rightLen
? ?newLeftIndex = leftIndex - totalLen*i,
? ? newRightIndex = rightIndex - totalLen*(i+1)+rightLen;
4扔枫、newText中刪除(newLeftIndex, newLeftIndex+leftLen)的標(biāo)簽汛聚,刪除(newRightIndex, newRightIndex+rightLen)的標(biāo)簽。
5短荐、i++倚舀,返回2。直到掃描結(jié)束忍宋。
6瞄桨、根據(jù)下表表以及newText,構(gòu)造SpannableString讶踪,返回芯侥。