如何使用Spannable为指定文本设置红色并隐藏外层包裹标记
实现思路
- 用正则匹配所有
-[[xxx]]-格式的片段,同时提取包裹的目标文本 - 构建处理后的纯文本内容,同时记录每个目标文本在新文本中的起止索引
- 用
SpannableString承载最终文本,给对应索引区间添加红色前景色样式
代码实现(Kotlin版本)
import android.graphics.Color import android.text.SpannableString import android.text.style.ForegroundColorSpan import android.widget.TextView import java.util.regex.Pattern // 原始文本 val rawText = "The -[[community]]- is here to help you with -[[specific]]- coding, -[[algorithm]]-, or -[[language]]- problems." // 匹配规则:非贪婪匹配所有-[[xxx]]-片段,捕获中间的目标内容 val pattern = Pattern.compile("-\\[\\[(.*?)\\]\\]-") val matcher = pattern.matcher(rawText) val processedTextBuilder = StringBuilder() val spanPositionList = mutableListOf<Pair<Int, Int>>() var lastMatchEnd = 0 while (matcher.find()) { // 拼接当前匹配位置之前的普通文本 processedTextBuilder.append(rawText.substring(lastMatchEnd, matcher.start())) // 提取包裹的目标文本 val targetText = matcher.group(1) ?: "" // 记录目标文本在新字符串中的起止位置 val spanStart = processedTextBuilder.length processedTextBuilder.append(targetText) val spanEnd = processedTextBuilder.length spanPositionList.add(Pair(spanStart, spanEnd)) // 更新上一次匹配的结束位置 lastMatchEnd = matcher.end() } // 拼接最后一段剩余的普通文本 processedTextBuilder.append(rawText.substring(lastMatchEnd)) // 构建SpannableString并设置红色样式 val spannableString = SpannableString(processedTextBuilder) spanPositionList.forEach { (start, end) -> spannableString.setSpan( ForegroundColorSpan(Color.RED), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE ) } // 给TextView设置最终内容 textView.text = spannableString
注意事项
- 正则使用非贪婪匹配
.*?,避免多个包裹标签连在一起时匹配范围出错 - 样式标记默认用
SPAN_EXCLUSIVE_EXCLUSIVE,保证后续在对应区间前后插入文本不会继承红色样式,符合常规使用需求 - 如果需要额外添加加粗、下划线等样式,在对应区间额外添加
StyleSpan、UnderlineSpan等即可
内容的提问来源于stack exchange,提问作者Taha Sami
相关产品推荐
相关产品推荐

