效果图
TextDrawable.java
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import androidx.annotation.ColorInt;import androidx.annotation.DrawableRes;import androidx.annotation.IntRange;import androidx.appcompat.widget.AppCompatTextView;import com.haizhi.enforce.R;import org.jetbrains.annotations.NotNull;public class TextDrawable extends AppCompatTextView { private Drawable drawableLeft; private Drawable drawableRight; private Drawable drawableTop; private int tmpTopHeight = 0; private boolean showCornerMark; private String cornerMarkText; private Drawable cornerMarkBackground; private Integer cornerMarkBackgroundColor; private int cornerMarkWidth; private int cornerMarkHeight; private int cornerMarkTextSize; @ColorInt private int cornerMarkTextColor; private int cornerMarkTextPadding; private Paint cornerMarkPaint; private Paint cornerMarkBgPaint; private Path cornerMarkBgPath; private int leftWidth; private int rightWidth; private int topWidth; private int leftHeight; private int rightHeight; private int topHeight; private final Context mContext; private final int defaultDrawableSize; private final int defaultCornerMarkSize; private int viewWidth; private int viewHeight; public TextDrawable(Context context) { this(context, null); } public TextDrawable(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TextDrawable(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; defaultDrawableSize = dip2px(context, 20); defaultCornerMarkSize = dip2px(context, 5); init(context, attrs); } private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextDrawable); drawableLeft = typedArray.getDrawable(R.styleable.TextDrawable_leftDrawable); drawableRight = typedArray.getDrawable(R.styleable.TextDrawable_rightDrawable); drawableTop = typedArray.getDrawable(R.styleable.TextDrawable_topDrawable); if (drawableLeft != null) { leftWidth = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_leftDrawableWidth, defaultDrawableSize); leftHeight = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_leftDrawableHeight, defaultDrawableSize); } if (drawableRight != null) { rightWidth = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_rightDrawableWidth, defaultDrawableSize); rightHeight = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_rightDrawableHeight, defaultDrawableSize); } if (drawableTop != null) { topWidth = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_topDrawableWidth, defaultDrawableSize); topHeight = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_topDrawableHeight, defaultDrawableSize); } // 角标 showCornerMark = typedArray.getBoolean(R.styleable.TextDrawable_cornerMarkShow, false); if (showCornerMark) { cornerMarkText = typedArray.getString(R.styleable.TextDrawable_cornerMark); try { cornerMarkBackground = typedArray.getDrawable(R.styleable.TextDrawable_cornerMarkBackgroud); } finally { if (cornerMarkBackground == null) { cornerMarkBackgroundColor = typedArray.getColor(R.styleable.TextDrawable_cornerMarkBackgroud, context.getColor(R.color.transparent)); } } cornerMarkWidth = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_cornerMarkWidth, defaultCornerMarkSize); cornerMarkHeight = typedArray.getDimensionPixelOffset(R.styleable.TextDrawable_cornerMarkHeight, defaultCornerMarkSize); cornerMarkTextSize = typedArray.getDimensionPixelSize(R.styleable.TextDrawable_cornerMarkTextSize, dip2px(context, 10)); cornerMarkTextColor = typedArray.getColor(R.styleable.TextDrawable_cornerMarkTextColor, context.getColor(R.color.red)); cornerMarkTextPadding = typedArray.getDimensionPixelSize(R.styleable.TextDrawable_cornerMarkPadding, dip2px(context, 4)); cornerMarkPaint = new Paint(); cornerMarkPaint.setTextSize(cornerMarkTextSize); cornerMarkPaint.setColor(cornerMarkTextColor); cornerMarkPaint.setTextAlign(Paint.Align.LEFT);// 右对齐 } } public int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int compoundPaddingTop = getCompoundPaddingTop(); final int compoundPaddingRight = getCompoundPaddingRight(); if (drawableLeft != null) { drawableLeft.setBounds(0, 0, leftWidth, leftHeight); } if (drawableRight != null) { drawableRight.setBounds(0, 0, rightWidth, rightHeight); } if (drawableTop != null) { drawableTop.setBounds(0, 0, topWidth, topHeight); tmpTopHeight = topHeight; } if (cornerMarkBackground != null && showCornerMark) { cornerMarkBackground.setBounds( viewWidth - cornerMarkWidth - compoundPaddingRight - 2 * cornerMarkTextPadding, compoundPaddingTop - tmpTopHeight, viewWidth - compoundPaddingRight, compoundPaddingTop + cornerMarkHeight + 2 * cornerMarkTextPadding - tmpTopHeight ); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWidth = w; viewHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); final int compoundPaddingTop = getCompoundPaddingTop(); final int compoundPaddingRight = getCompoundPaddingRight(); this.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, null); // 画角标 if (showCornerMark && cornerMarkText != null) { Paint.FontMetricsInt fontMetricsInt = cornerMarkPaint.getFontMetricsInt(); int top = fontMetricsInt.top; int bottom = fontMetricsInt.bottom; // 角标文字宽高计算 float textWidth = cornerMarkPaint.measureText(cornerMarkText); float textHeight = (bottom - top) / 2f + bottom; if (cornerMarkWidth < textWidth) cornerMarkWidth = (int) textWidth; if (cornerMarkHeight < textHeight) cornerMarkHeight = (int) textHeight; // 先画背景 if (cornerMarkBackground != null) { cornerMarkBackground.draw(canvas); } else { if (cornerMarkBgPaint == null) { cornerMarkBgPath = new Path(); cornerMarkBgPaint = new Paint(); cornerMarkBgPaint.setColor(cornerMarkBackgroundColor); } //将原点移动到原点 canvas.translate(0, 0); //绘制角标背景 cornerMarkBgPath.moveTo(viewWidth - textWidth - compoundPaddingRight - 2 * cornerMarkTextPadding, compoundPaddingTop - tmpTopHeight); //将Path的起点移动到A cornerMarkBgPath.lineTo(viewWidth - compoundPaddingRight, compoundPaddingTop - tmpTopHeight); //连接AB cornerMarkBgPath.lineTo(viewWidth - compoundPaddingRight, textHeight + compoundPaddingTop + 2 * cornerMarkTextPadding - tmpTopHeight); //连接BC cornerMarkBgPath.lineTo(viewWidth - textWidth - compoundPaddingRight - 2 * cornerMarkTextPadding, textHeight + compoundPaddingTop + 2 * cornerMarkTextPadding - tmpTopHeight); //连接CD cornerMarkBgPath.close(); //闭合Path,即连接DA canvas.drawPath(cornerMarkBgPath, cornerMarkBgPaint); } // 角标内容 canvas.drawText( cornerMarkText, viewWidth - textWidth - compoundPaddingRight - cornerMarkTextPadding, (bottom - top) / 2f + 1 + compoundPaddingTop + cornerMarkTextPadding - tmpTopHeight, cornerMarkPaint ); } } public void setDrawableLeft(Drawable drawableLeft) { this.drawableLeft = drawableLeft; invalidate(); } public void setDrawableLeft(@DrawableRes int drawableLeftRes) { this.drawableLeft = mContext.getResources().getDrawable(drawableLeftRes); invalidate(); } public void setDrawableRight(Drawable drawableRight) { this.drawableRight = drawableLeft; invalidate(); } public void setDrawableRight(@DrawableRes int drawableRightRes) { this.drawableRight = mContext.getResources().getDrawable(drawableRightRes); invalidate(); } public void setDrawable(Drawable drawableTop) { this.drawableTop = drawableTop; invalidate(); } public void setDrawableTop(@DrawableRes int drawableTopRes) { this.drawableTop = mContext.getResources().getDrawable(drawableTopRes); invalidate(); } public void setCornerMarkText(@NotNull String text) { this.cornerMarkText = text; } public void setCornerMarkWidth(@IntRange(from = 0)int width) { this.cornerMarkWidth = width; } public void setCornerMarkHeight(@IntRange(from = 0)int height) { this.cornerMarkHeight = height; } public void setCornerMarkTextSize(@IntRange(from = 0)int textSize) { this.cornerMarkTextSize = textSize; if (cornerMarkPaint != null) { cornerMarkPaint.setTextSize(textSize); } } public void setCornerMarkTextColor(@ColorInt int color) { this.cornerMarkTextColor = color; if (cornerMarkPaint != null) { cornerMarkPaint.setColor(color); } } public void setCornerMarkTextPadding(@IntRange(from = 0) int padding) { this.cornerMarkTextPadding = padding; }}
attrs.xml