Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReplacementSpan's draw() method isn't called

I set background in string like that:

spanString.setSpan(new BackgroundColorSpan(color), 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

But I would like to increase left and right padding in this background so I created custom span

public class PaddingBackgroundSpan extends ReplacementSpan {
private int mBackgroundColor;
private int mForegroundColor;

public PaddingBackgroundSpan(int backgroundColor, int foregroundColor) {
    this.mBackgroundColor = backgroundColor;
    this.mForegroundColor = foregroundColor;
}

@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
    return Math.round(measureText(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) {
    RectF rect = new RectF(x, top, x + measureText(paint, text, start, end), bottom);
    paint.setColor(mBackgroundColor);
    canvas.drawRect(rect, paint);
    paint.setColor(mForegroundColor);
    canvas.drawText(text, start, end, x, y, paint);
}

private float measureText(Paint paint, CharSequence text, int start, int end) {
    return paint.measureText(text, start, end);
}

I use my span by:

spanString.setSpan(new PaddingBackgroundSpan(color1, color2), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Unfortunately, my draw() method isn't called. getSize() is called correctly.

like image 896
qbait Avatar asked Nov 19 '13 10:11

qbait


1 Answers

The documentation for ReplacementSpan.getSize() provides the answer:

Returns the width of the span. Extending classes can set the height of the span by updating attributes of Paint.FontMetricsInt. If the span covers the whole text, and the height is not set, draw() will not be called for the span.

Make sure to update Paint.FontMetricsInt with proper values to fix the problem.

In my case, I just took the metrics from the TextView's Paint:

@Override
public int getSize(
        Paint paint,
        CharSequence text,
        int start,
        int end,
        Paint.FontMetricsInt fm) {
    final Paint.FontMetrics paintFontMetrics = paint.getFontMetrics();
    if (fm != null) {
        fm.ascent = (int) paintFontMetrics.ascent;
        fm.bottom = (int) paintFontMetrics.bottom;
        fm.descent = (int) paintFontMetrics.descent;
        fm.leading = (int) paintFontMetrics.leading;
        fm.top = (int) paintFontMetrics.top;
    }
    //...
}
like image 95
Ash Avatar answered Sep 27 '22 18:09

Ash