Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aligning ImageSpan with Spanable String

I know there are many questions of the same type available and I have tried so many solutions but all of them are not meeting my requirements.

My problem is that I have to add a dynamic line spacing between the text containing Spanable strings and Imagespan but when I add the line spacing the alignment of the text and image gets distorted.

I have tried almost all of the solutions available on Stackoverflow like this, this & this but all in vein. I have attached screenshots

  1. Screenshot before adding dynamic line spacing

Screenshot before adding dynamic line spacing 2. Screenshot after adding dynamic line spacing

Screenshot after adding dynamic line spacing

Any help will be highly appreciated. Thanks in advance!

like image 756
rana_sadam Avatar asked Jul 07 '17 10:07

rana_sadam


1 Answers

Use "y" in onDraw method to find the baseline of text and then align the drawable to baseline of text view

public class VerticalImageSpan extends ImageSpan {



 public VerticalImageSpan(Drawable drawable) {
        super(drawable);
    }

    /**
     * update the text line height
     */
    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end,
                       Paint.FontMetricsInt fontMetricsInt) {
        Drawable drawable = getDrawable();
        Rect rect = drawable.getBounds();
        if (fontMetricsInt != null) {
            Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
            int fontHeight = fmPaint.descent - fmPaint.ascent;
            int drHeight = rect.bottom - rect.top;
            int centerY = fmPaint.ascent + fontHeight / 2;

            fontMetricsInt.ascent = centerY - drHeight / 2;
            fontMetricsInt.top = fontMetricsInt.ascent;
            fontMetricsInt.bottom = centerY + drHeight / 2;
            fontMetricsInt.descent = fontMetricsInt.bottom;
        }
        return rect.right;
    }

    /**
     * see detail message in android.text.TextLine
     *
     * @param canvas the canvas, can be null if not rendering
     * @param text   the text to be draw
     * @param start  the text start position
     * @param end    the text end position
     * @param x      the edge of the replacement closest to the leading margin
     * @param top    the top of the line
     * @param y      the baseline
     * @param bottom the bottom of the line
     * @param paint  the work paint
     */
    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end,
                     float x, int top, int y, int bottom, Paint paint) {

        Drawable drawable = getDrawable();
        canvas.save();
        Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
        int fontHeight = fmPaint.descent - fmPaint.ascent;
        int centerY = y + fmPaint.descent - fontHeight / 2;
        int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
        canvas.translate(x, transY);
        drawable.draw(canvas);
        canvas.restore();
    }

}
like image 185
AwaisMajeed Avatar answered Sep 26 '22 03:09

AwaisMajeed