自定义Drawable,实现“原创”文本Table效果

1.自定义Drawable,绘制“原创”文本字符串

public class LabelDrawable extends Drawable {
    private String tag;
    private Paint paint;
    private String labelText;
    private float textSize;
    private float labelWidth;
    private float labelHeight;
    private float leftPadding;
    private float rightPadding;
    private float labelLeftRightPadding;
    private float labelTopBottomPadding;
    private float borderWidth;
    private float round;

    private float strokeWidth;

    public LabelDrawable(String tag, String labelText, float textSize) {
        this.tag = tag;
        this.labelText = labelText;
        this.textSize = textSize;
        this.paint = new Paint();
        this.paint.setColor(0xffff6f00);
        this.paint.setAntiAlias(true);

        this.paint.setTextSize(textSize);
        this.labelWidth = this.paint.measureText(labelText);
        this.labelHeight = this.paint.descent() - this.paint.ascent();

        this.strokeWidth = this.paint.getStrokeWidth();
    }

    public void setLeftPadding(float leftPadding) {
        this.leftPadding = leftPadding;
    }

    public void setRightPadding(float rightPadding) {
        this.rightPadding = rightPadding;
    }

    public void setLabelLeftRightPadding(float labelLeftRightPadding) {
        this.labelLeftRightPadding = labelLeftRightPadding;
    }

    public void setLabelTopBottomPadding(float labelTopBottomPadding) {
        this.labelTopBottomPadding = labelTopBottomPadding;
    }

    public void setBorderWidth(float borderWidth) {
        this.borderWidth = borderWidth;
    }

    public void setRound(float round) {
        this.round = round;
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        Rect bounds = getBounds();
        Log.w("zzh", tag + " bounds:" + bounds);

        Paint.FontMetrics fontMetrics = this.paint.getFontMetrics();

        float x = bounds.left + leftPadding + borderWidth + labelLeftRightPadding;
        float y = bounds.top + borderWidth + labelTopBottomPadding + Math.abs(fontMetrics.ascent);// - fontMetrics.descent;
        Log.w("zzh", tag + " x:" + x + " y:" + y);

        paint.setTextSize(textSize);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(this.strokeWidth);
        canvas.drawText(labelText, x, y, paint);

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderWidth);

        RectF borderRect = new RectF();
        borderRect.left     = bounds.left + leftPadding;
        borderRect.top      = bounds.top + labelTopBottomPadding;
        borderRect.right    = bounds.right - rightPadding;
        borderRect.bottom   = bounds.bottom - labelTopBottomPadding;

        canvas.drawRoundRect(borderRect, round, round, paint);

        Log.w("zzh", tag + " bounds:" + borderRect);
    }

    @Override
    public void setAlpha(int alpha) {
        this.paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    // 固有的大小
    @Override
    public int getIntrinsicHeight() {
        return (int) (borderWidth + labelTopBottomPadding + labelHeight + labelTopBottomPadding + borderWidth);
    }

    @Override
    public int getIntrinsicWidth() {
        return (int) (leftPadding + borderWidth + labelLeftRightPadding
                + labelWidth +
                labelLeftRightPadding + borderWidth + rightPadding);
    }
}

2、调整Drawable和文本的对齐

public class CenterAlignImageSpan extends ImageSpan {

    public CenterAlignImageSpan(Drawable drawable) {
        super(drawable);
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
                     @NonNull Paint paint) {
        Drawable b = getDrawable();
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
        canvas.save();
        canvas.translate(x, transY);//绘制图片位移一段距离
        b.draw(canvas);
        canvas.restore();
    }
}

3、写个帮助类,协调各类

public class LabelTextViewHelper{
    private TextView textView;
    private final float textSize;
    private final float leftPadding;
    private final float rightPadding;
    private final float borderWidth;
    private final float round;
    private final float labelLeftRightPadding;
    private final float labelTopBottomPadding;

    public LabelTextViewHelper(@NonNull TextView textView) {
        this.textView = textView;

        DisplayMetrics displayMetrics = textView.getResources().getDisplayMetrics();

        textSize        = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 13, displayMetrics);
        leftPadding     = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, displayMetrics);
        rightPadding    = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics);
        borderWidth     = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, displayMetrics);
        round           = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, displayMetrics);
        labelLeftRightPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6, displayMetrics);
        labelTopBottomPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, displayMetrics);
    }

    public void setLabelAndText(@NonNull String label, @NonNull String text){
        SpannableString sp = new SpannableString(label + text);

        //获取一张图片
        LabelDrawable drawable = new LabelDrawable("TextView", label, textSize);
        drawable.setLeftPadding(leftPadding);
        drawable.setRightPadding(rightPadding);
        drawable.setLabelLeftRightPadding(labelLeftRightPadding);
        drawable.setLabelTopBottomPadding(labelTopBottomPadding);
        drawable.setBorderWidth(borderWidth);
        drawable.setRound(round);
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

        //居中对齐imageSpan
        ImageSpan imageSpan = new CenterAlignImageSpan(drawable);
        sp.setSpan(imageSpan, 0, label.length(), ImageSpan.ALIGN_BASELINE);

        textView.setText(sp);
    }
}

4、实际使用

String labelText = "原创";

TextView textView = findViewById(R.id.main_txt);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
LabelTextViewHelper helper = new LabelTextViewHelper(textView);
helper.setLabelAndText(labelText, "10个高效的有氧减肥动作,快速瘦成一道闪电");

 

打赏