給定長文本與單詞數組,查找每個單詞在文本中的所有出現位置 (start, end),並用 `SpannableStringBuilder` 高亮顯示 (Android TextView)。
public static List findAllOccurrences(String text, String word) {
List positions = new ArrayList<>();
if (text == null || word == null || word.isEmpty()) return positions;
int index = 0;
while ((index = text.indexOf(word, index)) != -1) {
positions.add(new int[]{index, index + word.length()});
index += word.length(); // 移動到下一個可能位置,避免重疊匹配
}
return positions;
}
public static SpannableStringBuilder highlightKeywords(Context context, String text, String[] keywords, int highlightColor) {
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
for (String keyword : keywords) {
if (TextUtils.isEmpty(keyword)) continue;
List positions = findAllOccurrences(text, keyword);
for (int[] pos : positions) {
// 設置前景色高亮
ssb.setSpan(new ForegroundColorSpan(highlightColor), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 可選:背景色、粗體、點擊事件
// ssb.setSpan(new BackgroundColorSpan(Color.YELLOW), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// ssb.setSpan(new StyleSpan(Typeface.BOLD), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// ssb.setSpan(new ClickableSpan() { ... }, pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return ssb;
}
// 使用
TextView textView = findViewById(R.id.tv);
textView.setText(highlightKeywords(this, longText, new String[]{"關鍵詞1", "關鍵詞2"}, Color.RED));
textView.setMovementMethod(LinkMovementMethod.getInstance()); // 若包含 ClickableSpan
結束位置 = 開始位置 + 關鍵詞長度 (`word.length()`),注意 `Spanned.SPAN_EXCLUSIVE_EXCLUSIVE` 標誌決定插入字符時區間擴展行為。