效果图

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.yourpackage.R;
import org.jetbrains.annotations.NotNull;
/**
* @author octopus yan
* @email octopus_yan@foxmail.com
* @Description 可自定义图标的文字组件
* @createTime 2021-12-06 14:58:16
*/
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;
}
/**
* 设置角标文字大小 单位:px
*/
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
<declare-styleable name="TextDrawable">
<!--左图标-->
<attr name="leftDrawable" format="reference" />
<attr name="leftDrawableWidth" format="dimension" />
<attr name="leftDrawableHeight" format="dimension" />
<!--右图标-->
<attr name="rightDrawable" format="reference" />
<attr name="rightDrawableWidth" format="dimension" />
<attr name="rightDrawableHeight" format="dimension" />
<!--上图标-->
<attr name="topDrawable" format="reference" />
<attr name="topDrawableWidth" format="dimension" />
<attr name="topDrawableHeight" format="dimension" />
<!--角标-->
<attr name="cornerMarkShow" format="boolean" />
<attr name="cornerMark" format="integer|string" />
<attr name="cornerMarkPadding" format="dimension" />
<attr name="cornerMarkTextSize" format="dimension" />
<attr name="cornerMarkTextColor" format="color" />
<attr name="cornerMarkBackgroud" format="reference" />
<attr name="cornerMarkWidth" format="dimension" />
<attr name="cornerMarkHeight" format="dimension" />
</declare-styleable>
TextDrawable是一个自定义的Android TextView组件,它可以显示左侧、右侧和顶部的Drawable图标,并支持添加角标。角标可以自定义文字、颜色、大小等属性。该组件通过XML属性进行配置,例如设置图标尺寸和角标显示等。
3308

被折叠的 条评论
为什么被折叠?



