Android – 使用ReplacementSpan为SpannableStringBuilder添加保证金

前端之家收集整理的这篇文章主要介绍了Android – 使用ReplacementSpan为SpannableStringBuilder添加保证金前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在尝试在TextView / EditText中格式化Hashtags(比如Material Design Specs中提到的Chips).我可以使用ReplacementSpan格式化背景.但问题是我无法增加TextView / EditText中的行间距.见下图

enter image description here

问题是如何为主题标签添加顶部和底部边距?

这是我在文本中添加背景的代码

   /**
     * First draw a rectangle
     * Then draw text on top
     */
    @Override
    public void draw(Canvas canvas,CharSequence text,int start,int end,float x,int top,int y,int bottom,Paint paint) {
        RectF rect = new RectF(x,top,x + measureText(paint,text,start,end),bottom);
        paint.setColor(backgroundColor);
        canvas.drawRoundRect(rect,CORNER_RADIUS,paint);
        paint.setColor(textColor);
        canvas.drawText(text,end,x,y,paint);
    }
最佳答案
我不久前遇到过类似的问题,这是我提出的解决方案:

在xml中托管TextView:

viewmodel.renderedTagBadges}">

ReplacementSpan的自定义版本

public class TagBadgeSpannable extends ReplacementSpan implements LineHeightSpan {

    private static int CORNER_RADIUS = 30;
    private final int textColor;
    private final int backgroundColor;
    private final int lineHeight;

    public TagBadgeSpannable(int lineHeight,int textColor,int backgroundColor) {
        super();
        this.textColor = textColor;
        this.backgroundColor = backgroundColor;
        this.lineHeight = lineHeight;
    }

    @Override
    public void draw(Canvas canvas,Paint paint) {
        final float textSize = paint.getTextSize();
        final float textLength = x + measureText(paint,end);
        final float badgeHeight = textSize * 2.25f;
        final float textOffsetVertical = textSize * 1.45f;

        RectF badge = new RectF(x,textLength,y + badgeHeight);
        paint.setColor(backgroundColor);
        canvas.drawRoundRect(badge,paint);

        paint.setColor(textColor);
        canvas.drawText(text,y + textOffsetVertical,paint);
    }

    @Override
    public int getSize(Paint paint,Paint.FontMetricsInt fm) {
        return Math.round(paint.measureText(text,end));
    }

    private float measureText(Paint paint,int end) {
        return paint.measureText(text,end);
    }

    @Override
    public void chooseHeight(CharSequence charSequence,int i,int i1,int i2,int i3,Paint.FontMetricsInt fontMetricsInt) {
        fontMetricsInt.bottom += lineHeight;
        fontMetricsInt.descent += lineHeight;
    }
}

最后是一个创建Spannable的构建器

public class AndroidTagBadgeBuilder implements TagBadgeBuilder {

    private final SpannableStringBuilder stringBuilder;
    private final String textColor;
    private final int lineHeight;

    public AndroidTagBadgeBuilder(SpannableStringBuilder stringBuilder,int lineHeight,String textColor) {
        this.stringBuilder = stringBuilder;
        this.lineHeight = lineHeight;
        this.textColor = textColor;
    }

    @Override
    public void appendTag(String tagName,String badgeColor) {
        final String nbspSpacing = "\u202F\u202F"; // none-breaking spaces

        String badgeText = nbspSpacing + tagName + nbspSpacing;
        stringBuilder.append(badgeText);
        stringBuilder.setSpan(
            new TagBadgeSpannable(lineHeight,Color.parseColor(textColor),Color.parseColor(badgeColor)),stringBuilder.length() - badgeText.length(),stringBuilder.length()- badgeText.length() + badgeText.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        );
        stringBuilder.append("  ");
    }

    @Override
    public CharSequence getTags() {
        return stringBuilder;
    }

    @Override
    public void clear() {
        stringBuilder.clear();
        stringBuilder.clearSpans();
    }
}

结果将如下所示:

Rendered badges in TextView

根据自己的喜好调整TagBadgeSpannable中的度量.

我已经使用此代码上传了一个非常小的示例项目到github,所以请随时查看.

注意:该示例使用Android Databinding并编写MVVM样式

猜你在找的Android相关文章