将Padding/Margin添加到Spannable

22

我正在使用 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);

这是我的结果:

Have

而这是我想要达到的效果:

Want

你可以看到,我试图为“9.5”和“excellent!”字符串添加填充,但是到目前为止我还没有找到解决方案。

有没有办法为这些Spannables添加填充/边距呢?

2个回答

12
您可以使用 ReplacementSpan。在您的 Activity 中:
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);
    }
}

3
对我来说不起作用。背景颜色没问题,但文本位置不正确。 - AsafK
@AsafK,请发布您的TextView布局。 - Andrea Motto

7
你可以使用RoundedBackgroundSpan。
  1. It supports both padding and margin
  2. It avoids the situation where the text is not centered in the TextView.
  3. It can also set BackgroundColor for the text.

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接