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

如何通过drawLeadingMargin在文本末尾添加带样式的引号

问题修复:引用文本尾引号位置错误

错误原因分析

当前代码里尾引号的坐标计算存在两个核心问题:

  1. Y坐标错误:误用了首行文本的基线坐标,没有匹配到引用文本最后一行的基线,导致换行时尾引号位置跑偏
  2. X坐标错误:textSize*text.length()的计算逻辑完全不成立——text是整个TextView的内容,不是当前引用span的范围,而且没有考虑文本排版后的实际宽度和布局方向(比如RTL)

修正方案及代码

修改drawLeadingMargin方法中尾引号的绘制逻辑,替换错误的坐标计算代码:

public class ZMQuoteSpan extends MetricAffectingSpan {
    // 省略其他代码...
    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom,
                                  CharSequence text, int start, int end, boolean first, Layout layout) {

        Paint.Style style = p.getStyle();
        int color = p.getColor();
        boolean isFakeBoldText = p.isFakeBoldText();
        Typeface oldTypeface = p.getTypeface();

        Typeface typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC);
        p.setTypeface(typeface);
        p.setColor(QUOTE_SYSBOLM_COLOR);
        p.setFakeBoldText(true);

        // 首引号绘制(保留原有正确逻辑)
        int spanStart = ((Spanned) text).getSpanStart(this);
        int spanEnd = ((Spanned) text).getSpanEnd(this);
        int startY = layout.getLineBaseline(layout.getLineForOffset(spanStart));
        c.drawText("\"", x, startY, p);

        // --- 修正尾引号的坐标计算 ---
        int endLine = layout.getLineForOffset(spanEnd);
        int endY = layout.getLineBaseline(endLine);
        // 获取尾引号所在行的右端X坐标
        float endLineRight = layout.getLineLeft(endLine) + layout.getLineWidth(endLine);
        // 计算引号的X位置:考虑布局方向(dir)和引号自身宽度
        float quoteWidth = p.measureText("\"");
        float quoteX = endLineRight - quoteWidth * dir;
        c.drawText("\"", quoteX, endY, p);
        // ---------------------------

        p.setStyle(style);
        p.setColor(color);
        p.setFakeBoldText(isFakeBoldText);
        p.setTypeface(oldTypeface);
    }
}

关键修正点说明

  • 用spanEnd对应的行基线endY作为尾引号的Y坐标,确保换行时尾引号出现在引用文本的最后一行
  • 通过layout.getLineLeft(endLine) + layout.getLineWidth(endLine)获取引用文本最后一行的实际右端位置
  • 用p.measureText("\"")获取引号自身宽度,结合dir参数处理RTL布局的偏移,保证引号紧贴文本末尾

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:50:39