Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageSpan is cut off / incorrectly aligned

Tags:

android

I am implementing emoticons using the following code:

            builder.setSpan(new ImageSpan(mContext, resId, ImageSpan.ALIGN_BASELINE),
                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );

The result (builder) is set as text to a TextView. It works just fine if the span is surrounded by text, i.e. when the start > 0 and the end < length - 1, but the image is cut off (shifted up) if there is no text around it. how do I fix that?

Thanks a lot.

like image 206
Asahi Avatar asked Jul 15 '10 06:07

Asahi


2 Answers

Following on to your solution, here is my custom DynamicDrawableSpan I use in place of ImageSpan. The draw() method (copied from DynamicDrawableSpan and modified) ensures that there is text before aligning with the baseline.

class StickerSpan extends DynamicDrawableSpan {
    Drawable mDrawable;

    public StickerSpan(Context context, Bitmap bitmap) {
        super(DynamicDrawableSpan.ALIGN_BASELINE);
        setBitmap(context, bitmap);
    }

    public void setBitmap(Context context, Bitmap bitmap) {
        mDrawable = new BitmapDrawable(context.getResources(), bitmap);
        int width = mDrawable.getIntrinsicWidth();
        int height = mDrawable.getIntrinsicHeight();
        mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); 
    }

    @Override
    public Drawable getDrawable() {
        return mDrawable;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text,
                     int start, int end, float x, 
                     int top, int y, int bottom, Paint paint) {
        Drawable b = mDrawable;
        canvas.save();

        int transY = bottom - b.getBounds().bottom;
        if (mVerticalAlignment == ALIGN_BASELINE) {
            int textLength = text.length();
            for (int i = 0; i < textLength; i++) {
                if (Character.isLetterOrDigit(text.charAt(i))) {
                    transY -= paint.getFontMetricsInt().descent;
                    break;
                }
            }
        }

        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }
}
like image 171
bjdodson Avatar answered Oct 12 '22 07:10

bjdodson


I also ran into this issue and could not find a proper solution. The workaround I used looks like this:

if(message.length() == 1){
//This is a hack to get past an android bug that misaligns ImageSpan's when they are all alone.
    message += " ";
}
builder = new SpannableStringBuilder(message);
like image 39
plowman Avatar answered Oct 12 '22 07:10

plowman