如何实现忽略大小写的Spantext文本着色功能
实现忽略大小写的TextView文本着色
原代码的问题在于使用indexOf()进行区分大小写的字符串查找,导致无法匹配大小写不同的目标文本。以下是两种可行的修改方案:
方案一:使用正则表达式匹配(推荐)
通过正则表达式的不区分大小写模式,一次性找到所有匹配的文本片段,再逐个设置着色效果:
public void _changeTextinView(final String _target, final int _colour, final TextView _tv) { String vString = (String) _tv.getText(); Spannable spanRange = new SpannableString(vString); // 构建不区分大小写的正则表达式 Pattern pattern = Pattern.compile(_target, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(vString); while (matcher.find()) { int startSpan = matcher.start(); int endSpan = matcher.end(); ForegroundColorSpan foreColour = new ForegroundColorSpan(_colour); spanRange.setSpan(foreColour, startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } _tv.setText(spanRange); }
关键改动说明
- 用
Pattern.CASE_INSENSITIVE标记创建正则表达式,实现不区分大小写的匹配 - 通过
Matcher.find()遍历所有匹配的文本位置,逐个设置ForegroundColorSpan
方案二:转换大小写后查找位置
将原字符串和目标文本统一转换为小写(或大写),找到匹配位置后再映射回原字符串的索引:
public void _changeTextinView(final String _target, final int _colour, final TextView _tv) { String vString = (String) _tv.getText(); String lowerVString = vString.toLowerCase(); String lowerTarget = _target.toLowerCase(); int targetLength = lowerTarget.length(); int startSpan = 0, endSpan = 0; Spannable spanRange = new SpannableString(vString); while (true) { startSpan = lowerVString.indexOf(lowerTarget, endSpan); if (startSpan < 0) break; endSpan = startSpan + targetLength; ForegroundColorSpan foreColour = new ForegroundColorSpan(_colour); spanRange.setSpan(foreColour, startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } _tv.setText(spanRange); }
关键改动说明
- 将原字符串和目标文本都转为小写,用
indexOf()查找匹配位置 - 找到的位置直接对应原字符串的索引,因为转换大小写不会改变字符串长度
- 保持原字符串的 Spannable 处理,不会修改原文本的大小写
测试时,调用_changeTextinView("a", Color.RED, textview1),就能让"aAaAaAa"中的所有a和A都变成红色。
内容的提问来源于stack exchange,提问作者Fiqih Hasroni
相关产品推荐
相关产品推荐

