自定义高亮文字的textview,匹配关键字词高亮,匹配可拆分的字词高亮
import android.graphics.Color;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HighlightTextView {
// 高亮文本
public static void highlightTextView(TextView textView, String text, String keyword) {
// 将文本和关键字转换为 SpannableString
SpannableString spannableText = new SpannableString(text);
// 创建 ForegroundColorSpan 并设置高亮颜色
ForegroundColorSpan highlightSpan = new ForegroundColorSpan(Color.RED);
// 编译正则表达式模式
Pattern pattern = Pattern.compile(keyword);
// 进行正则表达式匹配
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
// 在匹配到的部分添加高亮标记
spannableText.setSpan(highlightSpan, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// 设置 TextView 的文本为带有高亮标记的 SpannableString
textView.setText(spannableText);
}
// 示例用法
public static void main(String[] args) {
TextView textView = findViewById(R.id.textView);
String text = "这是一个示例文本";
String keyword = "示";
highlightTextView(textView, text, keyword);
}
}
import android.graphics.Color;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
public class HighlightTextView {
// 高亮文本
public static void highlightTextView(TextView textView, String text, String[] keywords) {
// 将文本转换为 SpannableString
SpannableString spannableText = new SpannableString(text);
// 创建 ForegroundColorSpan 并设置高亮颜色
ForegroundColorSpan highlightSpan = new ForegroundColorSpan(Color.RED);
for (String keyword : keywords) {
// 对每个关键字进行正则表达式匹配和高亮处理
Pattern pattern = Pattern.compile(keyword);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
spannableText.setSpan(highlightSpan, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
// 设置 TextView 的文本为带有高亮标记的 SpannableString
textView.setText(spannableText);
}
// 示例用法
public static void main(String[] args) {
TextView textView = findViewById(R.id.textView);
String text = "这是一个示例文本";
String[] keywords = {"示", "例"};
highlightTextView(textView, text, keywords);
}
}
为什么只匹配高亮最后一个词呢,前面匹配的都没有高亮
在上面提供的示例代码中,为了为每个关键词都做高亮处理,需要在匹配到关键词时都对其进行Span设置。但是,在示例代码中进行Span设置时,每次设置新的Span时会覆盖之前设置的Span,因此只会显示最后一个匹配到的关键词的高亮效果。
要解决这个问题,可以修改为为每个匹配关键词的区间都创建一个新的Span,而不是覆盖之前的Span。以下是更新后的代码:
public void setHighlightedText(String fullText, String highlightText, String[] keywords) {
this.fullText = fullText;
this.highlightText = highlightText;
SpannableStringBuilder spannable = new SpannableStringBuilder(fullText);
for (String keyword : keywords) {
Pattern pattern = Pattern.compile(Pattern.quote(keyword), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(fullText);
while (matcher.find()) {
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
spannable.setSpan(span, matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
setText(spannable);
}
在上述代码中,while (matcher.find())
循环中会从第一个匹配到的关键词开始,所以第一个关键词可能会有高亮效果覆盖或遗漏。要解决这个问题,可以按照以下方式调整代码:
public void setHighlightedText(String fullText, String highlightText, String[] keywords) {
this.fullText = fullText;
this.highlightText = highlightText;
SpannableStringBuilder spannable = new SpannableStringBuilder(fullText);
for (String keyword : keywords) {
Pattern pattern = Pattern.compile(Pattern.quote(keyword), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(spannable);
while (matcher.find()) {
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
spannable.setSpan(span, matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
setText(spannable);
}
通过添加 (?i)
到正则表达式中,我们可以确保不区分大小写地匹配关键词。这样可以保证所有关键词都能够被正确地高亮显示,包括第一个关键词
public void setHighlightedText(String fullText, String highlightText, String[] keywords) {
this.fullText = fullText;
this.highlightText = highlightText;
SpannableStringBuilder spannable = new SpannableStringBuilder(fullText);
for (String keyword : keywords) {
Pattern pattern = Pattern.compile("(?i)" + Pattern.quote(keyword));
Matcher matcher = pattern.matcher(spannable);
while (matcher.find()) {
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
spannable.setSpan(span, matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
setText(spannable);
}