You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改EditText输入内容中双星号包裹文本在TextView的展示字体?

Android EditText 实现双星号包裹文本自定义字体显示

实现思路

核心是不修改用户原始输入内容,仅通过Span修改显示效果:监听输入变化,正则匹配所有成对**包裹的内容,将首尾的**设为透明隐藏,中间的文本区域设置你需要的字体样式,既满足显示要求,也能保留原始输入里的星号字符。

具体实现步骤

  • 首先给EditText添加文本变化监听,加标记位避免处理文本时触发循环回调
// 标记位:避免修改文本时重复触发监听
private boolean isFormatting = false;
private TextWatcher formatWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        if (isFormatting) return;
        isFormatting = true;
        // 处理富文本格式
        formatAsteriskText(s);
        isFormatting = false;
    }
};

// 初始化时给EditText设置监听
editText.addTextChangedListener(formatWatcher);
  • 编写匹配处理函数,用正则匹配所有成对双星号包裹的内容,设置对应Span
private void formatAsteriskText(Editable editable) {
    // 先清除之前设置的所有Span,避免重复叠加
    Object[] oldSpans = editable.getSpans(0, editable.length(), Object.class);
    for (Object span : oldSpans) {
        if (span instanceof ForegroundColorSpan || span instanceof TypefaceSpan || span instanceof StyleSpan) {
            editable.removeSpan(span);
        }
    }
    // 正则匹配成对的**包裹内容,非贪婪匹配+支持跨行
    Pattern pattern = Pattern.compile("\\*\\*(.*?)\\*\\*", Pattern.DOTALL);
    Matcher matcher = pattern.matcher(editable);
    // 你需要的自定义字体,提前加载好,如果只需要加粗可跳过这行
    Typeface customTypeface = Typeface.createFromAsset(getAssets(), "你的自定义字体文件名.ttf");
    while (matcher.find()) {
        int start = matcher.start();
        int end = matcher.end();
        // 1. 把前后的**设为透明,隐藏显示
        ForegroundColorSpan transparentSpan = new ForegroundColorSpan(Color.TRANSPARENT);
        editable.setSpan(transparentSpan, start, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ForegroundColorSpan transparentSpan2 = new ForegroundColorSpan(Color.TRANSPARENT);
        editable.setSpan(transparentSpan2, end - 2, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 2. 给中间的文本设置样式
        int contentStart = start + 2;
        int contentEnd = end - 2;
        if (contentStart < contentEnd) {
            // 如果只是要加粗,直接用下面这行即可
            // editable.setSpan(new StyleSpan(Typeface.BOLD), contentStart, contentEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 自定义字体用下面这行
            editable.setSpan(new TypefaceSpan(customTypeface), contentStart, contentEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
}

如果需要兼容Android 9以下版本的自定义字体设置,可自定义CustomTypefaceSpan继承MetricAffectingSpan,重写updateDrawState和updateMeasureState方法设置Typeface即可。

注意事项

  • 上述方案不会修改用户输入的原始内容,调用editText.getText().toString()获取到的文本还是包含原始**的,符合需求
  • 对于不成对的**不会被匹配,不会影响正常文本显示

内容的提问来源于stack exchange,提问作者Cynthia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:54:04