【问题标题】:Android BackgroundColorSpan breaking with lineSpacing less than 1Android BackgroundColorSpan 打破 lineSpacing 小于 1
【发布时间】:2022-07-07 12:50:37
【问题描述】:

我有一个textView,我这样做:

textView.setLineSpacing(1f, .70f);

然后我想只为textView 中的特定单词设置背景颜色,所以我尝试了这个:

spannableStringBuilder.setSpan(new BackgroundColorSpan(bckgndColor), spanStart, spanEnd, 0);

问题是因为 lineSpacing 它显示如下:

如果我要注释掉 lineSpacing() 行,我会这样做,这是完美的:

关于如何解决这个问题的任何想法?我尝试使用 BackgroundColorSpan 对象,但在挖掘类的代码后,我发现它只是这样做:

   /**
     * Updates the background color of the TextPaint.
     */
    @Override
    public void updateDrawState(@NonNull TextPaint textPaint) {
        textPaint.bgColor = mColor;
    }

即使我重写了该类,我也无法访问任何“矩形”值来调整或...不知道..

任何想法都值得赞赏。谢谢!

【问题讨论】:

  • 看起来您可能必须实现一个完全自定义的跨度。该背景绘制在TextLine 中处理,并且未对行距 AFAICT 进行任何调整。它总是从当前行边界的顶部到下一行的顶部绘制背景矩形,这就是为什么常规跨度在顶部延伸太远而在底部被切断的原因。
  • 我不确定你想如何调整这些背景,但here's a simple example 会将其“缩小”到实际的文本边界。看起来像:i.stack.imgur.com/iIdTl.png。这有点滥用ReplacementSpan,因为我们并没有真正替换任何东西,但这似乎是我们可以用于此类事情的唯一类型。它不适用于可能与此自定义跨度重叠的某些类型的跨度,但这里似乎不需要。
  • @MikeM。请写下你的答案,也许是整个代码作为回应。这正是我要找的!!!!谢谢!!!
  • 没问题!但是,我不再在这里发布答案,所以请随意完成这个问题。如果您决定发布答案,欢迎您在此处复制/粘贴我的任何或所有示例和图像。不过谢谢。我很感激这个提议。很高兴我能帮上忙。干杯!

标签: android android-spannable


【解决方案1】:

在 MikeM 的帮助下。这就是我要找的东西:

public class FauxBackgroundColorSpan extends ReplacementSpan {

    private final Rect tmpBounds = new Rect();
    private final int backgroundColor;

    public FauxBackgroundColorSpan(@ColorInt int color) {
        backgroundColor = color;
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start,
                       int end, Paint.FontMetricsInt fm) {
        // Necessary for full length spans to be drawn.
        if (fm != null) {
            final Paint.FontMetricsInt pfm = paint.getFontMetricsInt();
            fm.top = pfm.top;
            fm.ascent = pfm.ascent;
            fm.descent = pfm.descent;
            fm.bottom = pfm.bottom;
        }

        // This would normally be the width of whatever we're replacing the text with, but
        // we just return the text's own measure, since we're not really replacing anything.
        return getTextMeasure(paint, text, start, end);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start,
                     int end, float x, int top, int y, int bottom, Paint paint) {
        // Draw the background.
        final int previousColor = paint.getColor();
        final Paint.Style previousStyle = paint.getStyle();
        paint.setColor(backgroundColor);
        paint.setStyle(Paint.Style.FILL);

        final Rect bounds = tmpBounds;
        paint.getTextBounds(text.toString(), start, end, bounds);

        canvas.drawRect(x, y + bounds.top,
                x + getTextMeasure(paint, text, start, end), y + bounds.bottom, paint);

        paint.setStyle(previousStyle);
        paint.setColor(previousColor);

        // Draw the text we "replaced".
        canvas.drawText(text, start, end, x, y, paint);
    }

    private int getTextMeasure(Paint paint, CharSequence text, int start, int end) {
        return (int) (paint.measureText(text, start, end) + .5f);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 2013-11-28
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多