I am trying to change my string to make a badge with a number in the middle by using Spannable String. I can highlight the appropriate letter/number by setting the BackGrou
Here is my version based on @mvandillen answer. I also needed some margin at the beginning of span.
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.text.style.ReplacementSpan;
public class CoolBackgroundColorSpan extends ReplacementSpan {
private final int mBackgroundColor;
private final int mTextColor;
private final float mCornerRadius;
private final float mPaddingStart;
private final float mPaddingEnd;
private final float mMarginStart;
public CoolBackgroundColorSpan(int backgroundColor, int textColor, float cornerRadius, float paddingStart, float paddingEnd, float marginStart) {
super();
mBackgroundColor = backgroundColor;
mTextColor = textColor;
mCornerRadius = cornerRadius;
mPaddingStart = paddingStart;
mPaddingEnd = paddingEnd;
mMarginStart = marginStart;
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return (int) (mPaddingStart + paint.measureText(text.subSequence(start, end).toString()) + mPaddingEnd);
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
float width = paint.measureText(text.subSequence(start, end).toString());
RectF rect = new RectF(x - mPaddingStart + mMarginStart, top, x + width + mPaddingEnd + mMarginStart, bottom);
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, paint);
paint.setColor(mTextColor);
canvas.drawText(text, start, end, x + mMarginStart, y, paint);
}
}
How to use:
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
SpannableString staffTitleSpan = new SpannableString("staff: ");
SpannableString staffNameSpan = new SpannableString("John Smith");
staffNameSpan.setSpan(new StyleSpan(Typeface.BOLD), 0, staffNameSpan.length(), flag);
staffNameSpan.setSpan(new CoolBackgroundColorSpan(mStaffNameSpanBgColor, mStaffNameSpanTextColor, mStaffNameSpanBgRadius, mStaffNameSpanBgPaddingStart, mStaffNameSpanBgPaddingEnd, mStaffNameSpanMarginStart), 0, staffNameSpan.length(), flag);
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(staffTitleSpan);
builder.append(staffNameSpan);
staffTextView.setText(builder);
Preview:
Ok, so the question is a bit messy, here is my solution from DanieleB and mvandillen.
public class RoundedBackgroundSpan extends ReplacementSpan {
private static final int CORNER_RADIUS = 8;
private static final int PADDING_X = 12;
private int mBackgroundColor;
private int mTextColor;
/**
* @param backgroundColor background color
* @param textColor text color
*/
public RoundedBackgroundSpan(int backgroundColor, int textColor) {
mBackgroundColor = backgroundColor;
mTextColor = textColor;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return (int) (PADDING_X + paint.measureText(text.subSequence(start, end).toString()) + PADDING_X);
}
@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, top, x + width + 2 * PADDING_X, bottom);
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint);
paint.setColor(mTextColor);
canvas.drawText(text, start, end, x + PADDING_X, y, paint);
}
}
Tip: you can remove the textColor and user the default TextView color:
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
Paint paint1 = new Paint(paint);
float width = paint1.measureText(text.subSequence(start, end).toString());
RectF rect = new RectF(x, top, x + width + 2 * PADDING_X, bottom);
paint1.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint1);
canvas.drawText(text, start, end, x + PADDING_X, y, paint);
}