自定义高亮文字的textview,匹配关键字词高亮,匹配可拆分的字词高亮

自定义高亮文字的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);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值