安卓截取字符串,TextView显示并颜色标记+点击事件

这篇博客主要介绍在Android中如何截取字符串并在TextView中进行颜色标记,同时为标记部分添加点击事件。作者提供了三种不同的解决方案:1) 使用split方法分割字符串;2) 截取剩余字符串并遍历处理;3) 利用正则表达式截取需要标记的字符串。文章以具体的代码示例展示了解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安卓截取字符串,TextView显示并颜色标记+点击事件
对字符串中的多个带标记的字段,进行标记,并赋予点击事件。难点在于你如何处理字符串。
废话少说,直接进入正题

场景

要解析的字符串示例:

String str = "请问你是要查询<s>无线告警</s>还是下面的这些告警信息呢?<br />*<s>传输告警</s><br />*<s>故障单告警</s>(仅支持AGZ工单)<br />*<s>割接单告警</s><br />";

要求:将以上字符串以文本的形式展示出来,其中<s></s>中间的内容需红色显示,且点击该字体时弹出该内容,<br />为换行符,进行换行。

结果大概就这个样子:
结果大概就这个样子

plan 1

思路:使用split(String str)方法分割字符串,获取每个需要标记的字符串的起始和结束的位置,再使用SpannableStringBuilder进行文字标记及点击事件的处理。

上代码

public class SpannableStringBuilderActivity extends AppCompatActivity {

    private static final String TAG = "SpannableStringBuilderA";
    // 用于截取快捷点击项
    public static String INTERCEPT_START = "<s>";
    public static String INTERCEPT_END = "</s>";
    private String text = "请问你是要查询<s>无线告警</s>还是下面的这些告警信息呢?<br />*<s>传输告警</s><br />*<s>故障单告警</s>(仅支持AGZ工单)<br />*<s>割接单告警</s><br />";
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 布局就一个TextView
        setContentView(R.layout.activity_spannable_string_builder);
        initView();
    }

    private void initView() {
        mTextView = findViewById(R.id.textView);
        // 请不要问我为何不直接使用 \n, 源数据就是如此,当然如果后台愿意转义处理,请处理
        text = text.replaceAll("<br />","\n");
        // 这个方法是对字符串处理的核心,传入的第二个参数 如果你只有一个字符标记那就传一个字符
        List<Point> pointList = getSpecialContentPointList(text, INTERCEPT_START + "|" + INTERCEPT_END);

        SpannableStringBuilder spBuilder = new SpannableStringBuilder();
        // 添加字符时要把标记去掉,原因去看字符串的处理
        String showText = text.replaceAll(INTERCEPT_START,"");
        showText = showText.replaceAll(INTERCEPT_END,"");
        spBuilder.append(showText);
        for (Point point : pointList){
            // 添加颜色
            spBuilder.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorAccent)), point.x, point.y,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            final CharSequence clickText = (spBuilder.subSequence(point.x, point.y));
            // 点击事件
            spBuilder.setSpan(new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    Log.i(TAG, "onClick: 你现在点击的是" + clickText);
                }

                @Override
                public void updateDrawState(TextPaint ds) {
                    super.updateDrawState(ds);
                    ds.setColor(getResources().getColor(R.color.colorRed));
                    ds.setUnderlineText(false);
                }
            }, point.x, point.y, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        }
        mTextView.setText(spBuilder);
        // 这个必须加,否则点击事件不生效
        mTextView.setMovementMethod(LinkMovementMethod.getInstance());
    }

    public static List<Point> getSpecialContentPointList(String content, String regex) {
        List<Point> list = new ArrayList<>();
        if (isNull(content)) {
            return list;
        }
        if (isNull(regex)) {
            list.add(new Point(0, content.length()));
            return list;
        }
        String[] strs = content.split(regex);
        int x = 0;
        int y = 0;
        for (int i = 0; i < strs.length; i++) {
            Log.i(TAG, "getSpecialContentPointList: str = " + strs[i] );
            if (i % 2 == 1) {
                y = x + strs[i].length();
                list.add(new Point(x, y));
                x = x + strs[i].length();
            } else {
                x += strs[i].length();
            }
        }
        return list;
    }
    
}

plan 2

思路:截取字符串时,每次只处理截取之后剩余的字符串,然后遍历进行处理

plan3

思路:将需要标记的字符串,使用正则表达式截取出来变成一个List

后面两种抽空整理一下再写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值