Добавление отступа/поля к Spannable

Я использую BackgroundColorSpan для настройки частей файла TextView. Вот код, который у меня есть:

String s = "9.5 Excellent!";
s.setSpan(new BackgroundColorSpan(darkBlue, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new BackgroundColorSpan(darkBlue, 3, 14, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Что дает мне следующий результат:

Есть

И это то, чего я пытаюсь достичь:

Хочу

Как видите, я пытаюсь добавить дополнение к «9.5», а также к «отлично!» Строки, но я пока не смог найти решение.

Есть ли способ добавить это дополнение/маржу к этим Spannables?


person Henrique    schedule 29.11.2014    source источник


Ответы (2)


Вы можете использовать ReplacementSpan. В вашей деятельности:

TextView tagsTextView = (TextView) mView.findViewById(R.id.tagsTextView);
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();

SpannableString tag1 = new SpannableString("9.5");
stringBuilder.append(tag1);
stringBuilder.setSpan(new TagSpan(getResources().getColor(R.color.blue), getResources().getColor(R.color.white)), stringBuilder.length() - tag1.length(), stringBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

SpannableString tag2 = new SpannableString("excellent!");
stringBuilder.append(tag2);
stringBuilder.setSpan(new TagSpan(getResources().getColor(R.color.blueLight), getResources().getColor(R.color.blue)), stringBuilder.length() - tag2.length(), stringBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tagsTextView.setText(stringBuilder, TextView.BufferType.SPANNABLE);

TagSpan.java

public class TagSpan extends ReplacementSpan {
    private static final float PADDING = 50.0f;
    private RectF mRect;
    private int mBackgroundColor;
    private int mForegroundColor;

    public TagSpan(int backgroundColor, int foregroundColor) {
        this.mRect = new RectF();
        this.mBackgroundColor = backgroundColor;
        this.mForegroundColor = foregroundColor;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        // Background
        mRect.set(x, top, x + paint.measureText(text, start, end) + PADDING, bottom);
        paint.setColor(mBackgroundColor);
        canvas.drawRect(mRect, paint);

        // Text
        paint.setColor(mForegroundColor);
        int xPos = Math.round(x + (PADDING / 2));
        int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
        canvas.drawText(text, start, end, xPos, yPos, paint);
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
        return Math.round(paint.measureText(text, start, end) + PADDING);
    }
}
person Andrea Motto    schedule 13.03.2015
comment
не работает для меня. цвет фона в порядке, но текст нарисован не к месту. - person AsafK; 30.12.2015
comment
@AsafK, пожалуйста, опубликуйте свой макет TextView. - person Andrea Motto; 30.12.2015

Вы можете использовать RoundedBackgroundSpan.

  1. Он поддерживает как padding, так и margin
  2. Это позволяет избежать ситуации, когда текст не центрирован в TextView.
  3. Он также может установить BackgroundColor для текста.

    public class RoundedBackgroundSpan extends ReplacementSpan {
    
    
    private final int mBackgroundColor;
    private final int mTextColor;
    private final int mPaddingLeft;
    private final int mPaddingRight;
    private final int mMarginLeft;
    private final int mMarginRight;
    
    /**
     * Add rounded background for text in TextView.
     * @param backgroundColor background color
     * @param textColor       text color
     * @param paddingLeft     padding left(including background)
     * @param paddingRight    padding right(including background)
     * @param marginLeft      margin left(not including background)
     * @param marginRight     margin right(not including background)
     */
    public RoundedBackgroundSpan(int backgroundColor, int textColor,
                                 int paddingLeft,
                                 int paddingRight,
                                 int marginLeft,
                                 int marginRight) {
        mBackgroundColor = backgroundColor;
        mTextColor = textColor;
        mPaddingLeft = paddingLeft;
        mPaddingRight = paddingRight;
        mMarginLeft = marginLeft;
        mMarginRight = marginRight;
    }
    
    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end,
                       Paint.FontMetricsInt fm) {
        return (int) (mMarginLeft + mPaddingLeft +
                paint.measureText(text.subSequence(start, end).toString()) +
                mPaddingRight  + mMarginRight);
    }
    
    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
                     int bottom, Paint paint) {
        float width = paint.measureText(text.subSequence(start, end).toString());
        RectF rect = new RectF(x + mMarginLeft, top
                - paint.getFontMetricsInt().top + paint.getFontMetricsInt().ascent
                , x + width + mMarginLeft + mPaddingLeft + mPaddingRight, bottom);
        paint.setColor(mBackgroundColor);
        canvas.drawRoundRect(rect, rect.height() / 2, rect.height() / 2, paint);
        paint.setColor(mTextColor);
        canvas.drawText(text, start, end, x + mMarginLeft + mPaddingLeft,
                y - paint.getFontMetricsInt().descent / 2, paint);
    }
    }
    
person Francis Bacon    schedule 20.07.2017