Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageSpan alignment in TextView

I have a TextView which makes use of the android:lineSpacingMultiplier attribute to increase the spacing between lines, which works fine except for when I add an ImageSpan to the text.

This causes the image to be aligned to the bottom of the space between lines, not the baseline of the text (as is specified when I create it).

I tried using the android:lineSpacingExtra attribute, with some success, the image was still positioned lower than it should be, but not as much. Is there an alternate way of increasing the space between lines without messing up the vertical alignment of the ImageSpan?

like image 619
ScouseChris Avatar asked Jan 28 '14 13:01

ScouseChris


2 Answers

When you construct the ImageSpan, you can specify a vertical alignment, one of ImageSpan.ALIGN_BOTTOM or ImageSpan.ALIGN_BASELINE. I believe ImageSpan uses ALIGN_BOTTOM by default, so try a constructor that allows you to specify ALIGN_BASELINE.

like image 190
Karakuri Avatar answered Nov 10 '22 20:11

Karakuri


I've encountered the same problem, line spacing changed the baseline, so it takes down the images when you input text... you have to implement your custom image span, by changing its draw method:

public class CustomImageSpan extends ImageSpan{    
    public static final int ALIGN_TOP = 2;
    public static final int ALIGN_CUSTOM = 3;
    @Override
    public void draw(Canvas canvas, CharSequence text,
                     int start, int end, float x,
                     int top, int y, int bottom, Paint paint) {
        Drawable b = getCachedDrawable();
        canvas.save();

        int transY = bottom - b.getBounds().bottom;
        if (mVerticalAlignment == ALIGN_BASELINE) {
            transY -= paint.getFontMetricsInt().descent;
        } else if (mVerticalAlignment == ALIGN_TOP) {
            transY += paint.getFontMetricsInt().ascent;
        }

        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }
        private Drawable getCachedDrawable() {
            WeakReference<Drawable> wr = mDrawableRef;
            Drawable d = null;

            if (wr != null)
                d = wr.get();

            if (d == null) {
                d = getDrawable();
                mDrawableRef = new WeakReference<Drawable>(d);
            }

            return d;
        }

        private WeakReference<Drawable> mDrawableRef;
}
like image 39
YangKe Avatar answered Nov 10 '22 21:11

YangKe