I'm using BackgroundColorSpan
to customize parts of a TextView
.
Here's the code I have:
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);
Which gives me the following result:
And this is what I'm trying to achieve:
As you can see, I'm trying to add a padding to the "9.5" as well as the "excellent!" Strings, but I've been unable to find a solution so far.
Is there a way to add this padding/margin to these Spannables?
You can use ReplacementSpan
.
In your 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);
}
}
Francis Bacon
You can use RoundedBackgroundSpan.
- It supports both
padding
andmargin
- It avoids the situation where the text is not centered in the
TextView
. 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); } }
来源:https://stackoverflow.com/questions/27198155/adding-a-padding-margin-to-a-spannable