简体   繁体   中英

Android BackgroundColorSpan breaking with lineSpacing less than 1

I have got a textView to which I do this:

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

and then I would like to set a background color only to specific words in that textView so I've tried this:

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

The problem is that because of the lineSpacing it shows up like this:

在此处输入图像描述

as opposed to if I were to comment out the lineSpacing() line I would have this, which is perfect:

在此处输入图像描述

Any ideas on how to solve this problem? I tried playing around with the BackgroundColorSpan object, but after digging in the code of the class I see that it only does this:

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

and even if I override the class, I don't have access to any "Rect" value to adjust or ... dunno..

Any ideas are appreciated. Thank you !

With help from MikeM. this is what I was looking for:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM