ImageSpan отключен/неправильно выровнен

Я использую смайлики, используя следующий код:

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

Результат (построитель) задается как текст в TextView. Он отлично работает, если диапазон окружен текстом, то есть когда начало > 0 и конец < длина - 1, но изображение обрезается (сдвигается вверх), если вокруг него нет текста. как это исправить?

Большое спасибо.

Ответ 1

Ну, поскольку предложений нет, я собираюсь использовать следующее решение: если нет текстового флага ALIGN_BOTTOM, в противном случае используйте ALIGN_BASELINE...

Ответ 2

Следуя вашему решению, вот мой пользовательский DynamicDrawableSpan я использую вместо ImageSpan. Метод draw() (скопированный из DynamicDrawableSpan и измененный) гарантирует, что перед выравниванием с базовым уровнем будет текст.

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

Ответ 3

Я также столкнулся с этой проблемой и не смог найти правильное решение. Обходной путь, который я использовал, выглядит следующим образом:

if(message.length() == 1){
//This is a hack to get past an android bug that misaligns ImageSpan when they are all alone.
    message += " ";
}
builder = new SpannableStringBuilder(message);

Ответ 4

Попробуйте установить границу допустимого. Например:

        BitmapDrawable bmd = new BitmapDrawable(bm);
        int width = bmd.getIntrinsicWidth();
        int height = bmd.getIntrinsicHeight();
        bmd.setBounds(
                0,
                0,
                (int)width,
                (int)height);

        ImageSpan img = new ImageSpan(bmd);
        SpannableString spannableString = new SpannableString(
          someString);
        spannableString.setSpan(
          img, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Ответ 5

Для меня я просто не устанавливал границы растягиваемого, прежде чем передать его в ImageSpan.

Вы можете установить "внутренние границы" для рисования, выполнив что-то вроде:

Drawable drawable = // what you use to create/get your drawable
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ImageSpan span = new ImageSpan(drawable);