Выровнять текст вокруг центра ImageSpan по вертикали

У меня есть ImageSpan внутри фрагмента текста. Что я заметил, так это то, что окружающий текст всегда рисуется внизу текстовой строки — если быть более точным, размер текстовой строки увеличивается вместе с изображением, но базовая линия текста не смещается вверх. Когда изображение заметно больше размера текста, эффект довольно неприглядный.

Вот пример, контур показывает границы TextView: введите здесь описание изображения

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

введите здесь описание изображения

Вот ограничения, которыми я связан:

  • Я не могу использовать составные чертежи. Изображения должны быть в состоянии быть показаны между словами.
  • Текст может быть многострочным в зависимости от содержимого. Я не контролирую это.
  • Мои изображения больше окружающего текста, и я не могу уменьшить их размер. Хотя пример изображения выше больше, чем фактические изображения (чтобы продемонстрировать текущее поведение), фактические изображения все еще достаточно велики, чтобы эта проблема была заметна.

Я пытался использовать атрибут android:gravity="center_vertical" в TextView, но это не имеет никакого эффекта. Я полагаю, что это просто центрирует текст строки по вертикали, но внутри текстовой строки текст по-прежнему рисуется внизу.

Моя текущая мысль состоит в том, чтобы создать собственный диапазон, который смещает базовую линию текста в зависимости от высоты строки и текущего размера текста. Этот диапазон будет охватывать весь текст, и мне нужно будет вычислить пересечение с ImageSpan, чтобы избежать смещения изображений. Это звучит довольно сложно, и я надеюсь, что кто-то может предложить другой подход.

Любая помощь приветствуется!


person Karakuri    schedule 02.09.2014    source источник
comment
Вы придумали, как это сделать?   -  person WindsurferOak    schedule 26.10.2014
comment
Я хочу добиться того же, однако ответ ptilli make выглядит так, как будто он работает, но на самом деле он не делает то, что нужно делать, а именно центрирует текст с помощью курсора. Я дам вам знать, если я могу что-то выяснить   -  person jujux789    schedule 02.02.2015
comment
Ответы ниже работают только с изображением меньшей высоты, чем текст. Нам с автором нужен обратный трюк   -  person ElSajko    schedule 09.10.2015
comment
Возможный дубликат Выравнивание ImageSpan по верхней части TextView   -  person rds    schedule 29.06.2016
comment
@rds Я не пытаюсь выровнять диапазон изображения, поэтому не думаю, что это дубликат.   -  person Karakuri    schedule 30.06.2016


Ответы (11)


Это может быть немного поздно, но я нашел способ сделать это, независимо от размера изображения. Вам нужно создать класс, расширяющий ImageSpan, и переопределить методы getSize() и getCachedDrawable() (последний менять не нужно, но этот метод из DynamicDrawableSpan является закрытым и не может быть доступен другим способом из дочернего класса). В getSize(...) вы можете переопределить способ DynamicDrawableSpan установки подъема/верха/спуска/низа линии и добиться того, что вы хотите сделать.

Вот пример моего класса:

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;

import java.lang.ref.WeakReference;

public class CenteredImageSpan extends ImageSpan {

    // Extra variables used to redefine the Font Metrics when an ImageSpan is added
    private int initialDescent = 0;
    private int extraSpace = 0;

    public CenteredImageSpan(final Drawable drawable) {
        this(drawable, DynamicDrawableSpan.ALIGN_BOTTOM);
    }

    public CenteredImageSpan(final Drawable drawable, final int verticalAlignment) {
        super(drawable, verticalAlignment);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text,
                     int start, int end, float x,
                     int top, int y, int bottom, Paint paint) {
        getDrawable().draw(canvas);
    }

    // Method used to redefined the Font Metrics when an ImageSpan is added
    @Override
    public int getSize(Paint paint, CharSequence text,
                       int start, int end,
                       Paint.FontMetricsInt fm) {
        Drawable d = getCachedDrawable();
        Rect rect = d.getBounds();

        if (fm != null) {
            // Centers the text with the ImageSpan
            if (rect.bottom - (fm.descent - fm.ascent) >= 0) {
                // Stores the initial descent and computes the margin available
                initialDescent = fm.descent;
                extraSpace = rect.bottom - (fm.descent - fm.ascent);
            }

            fm.descent = extraSpace / 2 + initialDescent;
            fm.bottom = fm.descent;

            fm.ascent = -rect.bottom + fm.descent;
            fm.top = fm.ascent;
        }

        return rect.right;
    }

    // Redefined locally because it is a private member from DynamicDrawableSpan
    private Drawable getCachedDrawable() {
        WeakReference<Drawable> wr = mDrawableRef;
        Drawable d = null;

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

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

        return d;
    }

    private WeakReference<Drawable> mDrawableRef;
}

Дайте мне знать, если у вас возникнут проблемы с этим классом!

person jujux789    schedule 10.02.2015
comment
Как это использовать? Создавать тот же класс, я думаю, недостаточно. - person ElSajko; 08.10.2015
comment
Вам просто нужно заменить ImageSpan, который вы использовали, на CenteredImageSpan, и он автоматически центрирует ваше изображение с текстом - person jujux789; 08.10.2015
comment
но что, если я использую класс ImageSpan не напрямую, а с помощью Html.fromHtml(String)? - person ElSajko; 08.10.2015
comment
Есть ошибка, входная переменная нигде не существует, но ваш код пытается ее использовать. - person ElSajko; 08.10.2015
comment
Он работает только с высотой изображения меньше высоты текста. - person ElSajko; 09.10.2015
comment
@ElSajko Я только что попробовал это решение, и, похоже, оно отлично работает для изображения, превышающего высоту текста. В опубликованном коде есть некоторые ошибки: удалите переменную ввода в одном из конструкторов и измените =› на ›= в getSize() - person Karakuri; 09.10.2015
comment
По какой-то причине fm.descent = 3 * extraSpace / 8 + initialDescent; работает, а fm.descent = extraSpace / 2 + initialDescent; выравнивает текст по верху. Следуя этому руководству, добавьте изображение и текст: guides.codepath. ком/андроид/ - person auroranil; 30.12.2015
comment
как я могу использовать его, чтобы выровнять текст по нижней части изображения? - person Karioki; 28.06.2016
comment
@Karioki То, что вы описали, похоже на поведение по умолчанию в исходном сообщении. Я не думаю, что вы будете использовать этот код. - person Karakuri; 29.06.2016
comment
@Karakuri, извините, это была ошибка, я думал о «выравнивании по верхнему краю», получил свое решение, заменив fm.descent = extraSpace / 2 + initialDescent; по fm.descent = extraSpace + initialDescent; - person Karioki; 30.06.2016
comment
Пожалуйста, используйте paint.getFontMetricsInt() вместо fm. Поскольку fm является средней переменной - person chefish; 29.12.2016
comment
Я хочу знать, как мы можем использовать этот класс. CenteredImageSpan imageSpan = новый CenteredImageSpan (drawableResId, _____); что мне нужно передать как вторую переменную? - person Srikanth K; 05.06.2017
comment
@SrikanthK вам нужно пройти выравнивание, например. DynamicDrawableSpan.ALIGN_BOTTOM - person jujux789; 07.06.2017
comment
ошибка при переопределении методов draw и getbound - person rana_sadam; 07.07.2017

Мой ответ корректирует первый ответ. На самом деле я пробовал оба метода, описанные выше, и я не думаю, что они действительно центрированы по вертикали. Это сделало бы рисуемый более центральным, если бы он был помещен между ascent и descent, а не top и bottom. Что касается второго ответа, он выравнивает центр рисунка по базовой линии текста, а не по центру этого текста. Вот мое решение:

public class CenteredImageSpan extends ImageSpan {
  private WeakReference<Drawable> mDrawableRef;

  public CenteredImageSpan(Context context, final int drawableRes) {
    super(context, drawableRes);
  }

  @Override
  public int getSize(Paint paint, CharSequence text,
                     int start, int end,
                     Paint.FontMetricsInt fm) {
    Drawable d = getCachedDrawable();
    Rect rect = d.getBounds();

    if (fm != null) {
      Paint.FontMetricsInt pfm = paint.getFontMetricsInt();
      // keep it the same as paint's fm
      fm.ascent = pfm.ascent;
      fm.descent = pfm.descent;
      fm.top = pfm.top;
      fm.bottom = pfm.bottom;
    }

    return rect.right;
  }

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

    int drawableHeight = b.getIntrinsicHeight();
    int fontAscent = paint.getFontMetricsInt().ascent;
    int fontDescent = paint.getFontMetricsInt().descent;
    int transY = bottom - b.getBounds().bottom +  // align bottom to bottom
        (drawableHeight - fontDescent + fontAscent) / 2;  // align center to center

    canvas.translate(x, transY);
    b.draw(canvas);
    canvas.restore();
  }

  // Redefined locally because it is a private member from DynamicDrawableSpan
  private Drawable getCachedDrawable() {
    WeakReference<Drawable> wr = mDrawableRef;
    Drawable d = null;

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

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

    return d;
  }
}

Я также переписываю getSize, чтобы FontMetrics для рисования были такими же, как и для другого текста, иначе родительское представление не будет правильно переносить содержимое.

person Community    schedule 25.03.2015
comment
Это лучшее решение, которое также отвечает на мой вопрос. Это мой вопрос... stackoverflow.com/questions/31249475/ - person user3057361; 09.07.2015
comment
Работает отлично. Убедитесь, что вы предоставляете контекст и имя ресурса при использовании класса. Пример: ImageSpan imageSpan = new CenteredImageSpan(getApplicationContext(), R.drawable.ic_youricon) (в отличие от предыдущего примера) - person logic; 27.11.2015
comment
не работало на 4 устройствах значки hdpi 480x800 обрезаются внизу текст отображается правильно, но работал на устройствах xxhdpi - person chin87; 26.04.2016
comment
Замените розыгрыш этим розыгрышем: 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; // this is the key transY -= paint.getFontMetricsInt().descent / 2; canvas.translate(x, transY); b.draw(canvas); canvas.restore(); } - person chin87; 28.04.2016
comment
Если значок больше текста, значок будет обрезан. - person chefish; 28.12.2016
comment
Я настраиваю этот ответ ниже, а затем отлично работаю в моем случае. - person heng li; 21.06.2019

После прочтения исходного кода TextView я думаю, что мы можем использовать baseLine каждой текстовой строки, которая равна «y». И это будет работать, даже если вы установите lineSpaceExtra.

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

}
person xuqingqi    schedule 05.08.2016
comment
Это отлично работает независимо от размера изображения. В большинстве других ответов возникает проблема с обрезкой изображения, когда оно больше теста. Спасибо - person Sojan P R; 27.04.2018
comment
работает как шарм, спасибо, что нашли время и выяснили, что это сэкономило мне немного времени. - person KingKongCoder; 09.12.2018
comment
Это великолепно! Великолепный! Очаровательный! - person sudoExclaimationExclaimation; 31.12.2018
comment
Все лучшие ответы не работают, кроме этого. Спасибо! - person Oleksandr Albul; 16.03.2020

Я получил рабочее решение, создав класс, наследуемый от ImageSpan. .

Затем изменена реализация отрисовки из DynamicDrawableSpan. По крайней мере, эта реализация работает, когда высота моего изображения меньше высоты шрифта. Не уверен, как это работает для больших изображений, таких как ваше.

@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 bCenter = b.getIntrinsicHeight() / 2;
    int fontTop = paint.getFontMetricsInt().top;
    int fontBottom = paint.getFontMetricsInt().bottom;
    int transY = (bottom - b.getBounds().bottom) -
        (((fontBottom - fontTop) / 2) - bCenter);


    canvas.translate(x, transY);
    b.draw(canvas);
    canvas.restore();
}

Также пришлось повторно использовать реализацию из DynamicDrawableSpan, поскольку она была приватной.

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;

И вот как я использую его как статический метод, который вставляет изображение перед текстом.

public static CharSequence formatTextWithIcon(Context context, String text,
    int iconResourceId) {
    SpannableStringBuilder sb = new SpannableStringBuilder("X");

    try {
        Drawable d = context.getResources().getDrawable(iconResourceId);
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 
        CenteredImageSpan span = new CenteredImageSpan(d); 
        sb.setSpan(span, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        sb.append(" " + text); 
    } catch (Exception e) {
        e.printStackTrace();
        sb.append(text); 
    }

    return sb;

Возможно, это не очень хорошая практика, учитывая локализацию, но мне она подходит. Чтобы разместить изображения в середине текста, вам, естественно, потребуется заменить токены в тексте на интервалы.

person ptiili    schedule 14.10.2014
comment
что происходит, когда вы используете увеличенное изображение? - person Karakuri; 15.10.2014

Мой ответ корректирует ответ мисака-10032. работают идеально!

public static class CenteredImageSpan extends ImageSpan {
    private WeakReference<Drawable> mDrawableRef;

    CenteredImageSpan(Context context, final int drawableRes) {
        super(context, drawableRes);
    }

    public CenteredImageSpan(@NonNull Drawable d) {
        super(d);
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text,
                     int start, int end, float x,
                     int top, int y, int bottom, @NonNull Paint paint) {
        Drawable b = getCachedDrawable();
        canvas.save();
        int transY = top + (bottom - top - b.getBounds().bottom)/2;
        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }

    // Redefined locally because it is a private member from DynamicDrawableSpan
    private Drawable getCachedDrawable() {
        WeakReference<Drawable> wr = mDrawableRef;
        Drawable d = null;

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

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

        return d;
    }
}
person heng li    schedule 21.06.2019

Это решение обеспечивает вертикальное центрирование на основе фактического размера букв. Он поддерживает центрирование с использованием заглавных и строчных букв. Например, посмотрите на символ маркера рядом с буквой: X•. Это решение дает аналогичный эффект.

Это модифицированная версия ответа @WindRider. Кроме того, это в Котлине. И он поддерживает настройку размера Drawable.

Причина, по которой создано это решение, состоит в том, чтобы обеспечить лучший визуальный результат. Во многих других решениях используется подъем шрифта. Но в некоторых случаях это вызывает проблемы со зрением. Шрифт Roboto по умолчанию в Android, например, имеет подъем выше, чем типичная верхняя граница заглавной буквы. И из-за этого потребовались некоторые ручные настройки для правильного центрирования изображения.

class CenteredImageSpan(context: Context,
                        drawableRes: Int,
                        private val centerType: CenterType = CenterType.CAPITAL_LETTER,
                        private val customHeight: Int? = null,
                        private val customWidth: Int? = null) : ImageSpan(context, drawableRes) {

    private var mDrawableRef: WeakReference<Drawable?>? = null

    override fun getSize(paint: Paint, text: CharSequence,
                         start: Int, end: Int,
                         fontMetrics: FontMetricsInt?): Int {

        if (fontMetrics != null) {
            val currentFontMetrics = paint.fontMetricsInt
            // keep it the same as paint's Font Metrics
            fontMetrics.ascent = currentFontMetrics.ascent
            fontMetrics.descent = currentFontMetrics.descent
            fontMetrics.top = currentFontMetrics.top
            fontMetrics.bottom = currentFontMetrics.bottom
        }

        val drawable = getCachedDrawable()
        val rect = drawable.bounds
        return rect.right
    }

    override fun draw(canvas: Canvas,
                      text: CharSequence,
                      start: Int,
                      end: Int,
                      x: Float,
                      lineTop: Int,
                      baselineY: Int,
                      lineBottom: Int,
                      paint: Paint) {
        val cachedDrawable = getCachedDrawable()
        val drawableHeight = cachedDrawable.bounds.height()

        val relativeVerticalCenter = getLetterVerticalCenter(paint)

        val drawableCenter = baselineY + relativeVerticalCenter
        val drawableBottom = drawableCenter - drawableHeight / 2

        canvas.save()
        canvas.translate(x, drawableBottom.toFloat())
        cachedDrawable.draw(canvas)
        canvas.restore()
    }

    private fun getLetterVerticalCenter(paint: Paint): Int =
         when (centerType) {
            CenterType.CAPITAL_LETTER -> getCapitalVerticalCenter(paint)
            CenterType.LOWER_CASE_LETTER -> getLowerCaseVerticalCenter(paint)
        }

    private fun getCapitalVerticalCenter(paint: Paint): Int {
        val bounds = Rect()
        paint.getTextBounds("X", 0, 1, bounds)
        return (bounds.bottom + bounds.top) / 2
    }

    private fun getLowerCaseVerticalCenter(paint: Paint): Int {
        val bounds = Rect()
        paint.getTextBounds("x", 0, 1, bounds)
        return (bounds.bottom + bounds.top) / 2
    }


    // Redefined here because it's private in DynamicDrawableSpan
    private fun getCachedDrawable(): Drawable {

        val drawableWeakReference = mDrawableRef
        var drawable: Drawable? = null
        if (drawableWeakReference != null) drawable = drawableWeakReference.get()
        if (drawable == null) {
            drawable = getDrawable()!!

            val width = customWidth ?: drawable.intrinsicWidth
            val height = customHeight ?: drawable.intrinsicHeight

            drawable.setBounds(0, 0,
                               width, height)
            mDrawableRef = WeakReference(drawable)
        }
        return drawable

    }

    enum class CenterType {
        CAPITAL_LETTER, LOWER_CASE_LETTER
    }

}
person Vladislav M.    schedule 14.07.2020

При создании диапазона изображений вы должны добавить флаг вертикального выравнивания DynamicDrawableSpan.ALIGN_CENTER. Это должно выровнять центр изображения по тексту.

val mySpannable = SpannableString("    $YourText")
mySpannable.setSpan(ImageSpan(yourDrawable, DynamicDrawableSpan.ALIGN_CENTER), 0, 1, 0)
person rAm    schedule 07.12.2020

Вы можете использовать ImageSpan.ALIGN_CENTER. Я тестировал его на различных эмуляторах, и, кажется, он работает для API ‹ 29. Однако это хорошо работает только с шириной wrap_content. Из моих тестов, определяющих ширину программно или в xml, нарушается высота строки (?)

person mitsest    schedule 21.06.2021

Моя улучшенная версия: метрики рисуемого шрифта увеличены по сравнению с метриками текстового шрифта. Так что межстрочный интервал будет рассчитан правильно.

@Override
public int getSize(Paint paint, CharSequence text,
                   int start, int end,
                   Paint.FontMetricsInt fm) {
    Drawable d = getCachedDrawable();
    Rect rect = d.getBounds();
    float drawableHeight = Float.valueOf(rect.height());


    if (fm != null) {
        Paint.FontMetricsInt pfm = paint.getFontMetricsInt();
        float fontHeight = pfm.descent - pfm.ascent;
        float ratio = drawableHeight / fontHeight;

        fm.ascent = Float.valueOf(pfm.ascent * ratio).intValue();
        fm.descent = Float.valueOf(pfm.descent * ratio).intValue();
        fm.top = fm.ascent;
        fm.bottom = fm.descent;
    }
person Xiaofeng    schedule 20.10.2015

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

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.text.style.ImageSpan;

import java.lang.ref.WeakReference;

public class CustomImageSpan extends ImageSpan {

  /**
   * A constant indicating that the center of this span should be aligned
   * with the center of the surrounding text
   */
  public static final int ALIGN_CENTER = -12;
  private WeakReference<Drawable> mDrawable;
  private int mAlignment;

  public CustomImageSpan(Context context, final int drawableRes, int alignment) {
    super(context, drawableRes);
    mAlignment = alignment;
  }

  @Override
  public int getSize(Paint paint, CharSequence text,
                     int start, int end,
                     Paint.FontMetricsInt fm) {
    Drawable d = getCachedDrawable();
    Rect rect = d.getBounds();
    if (fm != null) {
      Paint.FontMetricsInt pfm = paint.getFontMetricsInt();
      fm.ascent = pfm.ascent;
      fm.descent = pfm.descent;
      fm.top = pfm.top;
      fm.bottom = pfm.bottom;
    }
    return rect.right;
  }

  @Override
  public void draw(@NonNull Canvas canvas, CharSequence text,
                   int start, int end, float x,
                   int top, int y, int bottom, @NonNull Paint paint) {
    if (mAlignment == ALIGN_CENTER) {
      Drawable cachedDrawable = getCachedDrawable();
      canvas.save();
      //Get the center point and set the Y coordinate considering the drawable height for aligning the icon vertically
      int transY = ((top + bottom) / 2) - cachedDrawable.getIntrinsicHeight() / 2;
      canvas.translate(x, transY);
      cachedDrawable.draw(canvas);
      canvas.restore();
    } else {
      super.draw(canvas, text, start, end, x, top, y , bottom, paint);
    }
  }

  // Redefined locally because it is a private member from DynamicDrawableSpan
  private Drawable getCachedDrawable() {
    WeakReference<Drawable> wr = mDrawable;
    Drawable d = null;
    if (wr != null) {
      d = wr.get();
    }
    if (d == null) {
      d = getDrawable();
      mDrawable = new WeakReference<>(d);
    }
    return d;
  }
}
person Rakesh Gopathi    schedule 13.03.2018

person    schedule
comment
работает хорошо и просто. Не могли бы вы объяснить значение параметра «нижний верхний, x y»? Я не могу понять и никаких объяснений документов. Спасибо - person Victor Choy; 01.12.2015
comment
замените отрисовку @misaka-10032 на эту отрисовку, и код работает на всех разрешениях - person chin87; 28.04.2016