每次给View加shape时都要写一堆的drawable文件,不容易管理,所以封装一下。
大体效果是这样的:
shape_line_color 边线颜色
shape_line_width 边线宽度
shape_content_color 内容区域颜色
shape_solid_line 是否是实线
shape_radius 四个角的角度
shape_left_top_radius 可以指定单个角度
具体代码:
<com.ycq.a16thread.ShapeTextView
android:layout_width="300dp"
android:layout_height="90dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:scaleType="fitXY"
android:text="start"
android:textColor="@color/white"
android:textSize="30dp"
app:shape_content_color="@color/purple_200"
app:shape_line_color="@color/teal_200"
app:shape_line_width="4dp"
app:shape_radius="45dp"
app:shape_solid_line="false" />
下边是全部的代码:
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import androidx.annotation.Nullable;
public class ShapeTextView extends androidx.appcompat.widget.AppCompatTextView {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
/**
* 边框线宽度
*/
private float mLineWidth;
/**
* 边框线一半宽度
*/
private float mHalfLineWidth;
private final RectF mLineRect = new RectF();
private final RectF mContentRect = new RectF();
private final float[] radiuses = new float[8];
private int mLineColor;
private int mContentColor;
private float mRadius;
private float mLeftTopRadius;
private float mLeftBottomRadius;
private float mRightTopRadius;
private float mRightBottomRadius;
private PathEffect mPathEffect;
private boolean mSolidLine;
public ShapeTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ShapeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, @Nullable AttributeSet attrs) {
TypedArray obtain = context.obtainStyledAttributes(attrs, R.styleable.ShapeTextView);
mLineWidth = obtain.getDimension(R.styleable.ShapeTextView_shape_line_width, 2);
mSolidLine = obtain.getBoolean(R.styleable.ShapeTextView_shape_solid_line, true);
mLineColor = obtain.getColor(R.styleable.ShapeTextView_shape_line_color, Color.parseColor("#396AF5"));
mContentColor = obtain.getColor(R.styleable.ShapeTextView_shape_content_color, Color.parseColor("#ffffff"));
mRadius = obtain.getDimension(R.styleable.ShapeTextView_shape_radius, -1);
mLeftTopRadius = obtain.getDimension(R.styleable.ShapeTextView_shape_left_top_radius, -1);
mLeftBottomRadius = obtain.getDimension(R.styleable.ShapeTextView_shape_left_bottom_radius, -1);
mRightTopRadius = obtain.getDimension(R.styleable.ShapeTextView_shape_right_top_radius, -1);
mRightBottomRadius = obtain.getDimension(R.styleable.ShapeTextView_shape_right_bottom_radius, -1);
obtain.recycle();
setRadius();
mHalfLineWidth = mLineWidth / 2f;
mPaint.setStrokeWidth(mLineWidth);
mPathEffect = new DashPathEffect(new float[]{20, 10}, 0);
}
private void setRadius() {
//radius优先级大于其他设置
if (mRadius == -1 &&
mLeftTopRadius == -1 && mLeftBottomRadius == -1 && mRightTopRadius == -1 && mRightBottomRadius == -1) {
setSameParams(0f);
} else if (mRadius != -1) {
setSameParams(mRadius);
} else {
//top-left
setTwoParams(0, 1, mLeftTopRadius == -1, mLeftTopRadius);
//top-right
setTwoParams(2, 3, mRightTopRadius == -1, mRightTopRadius);
//bottom-right
setTwoParams(4, 5, mRightBottomRadius == -1, mRightBottomRadius);
//bottom-left
setTwoParams(6, 7, mLeftBottomRadius == -1, mLeftBottomRadius);
}
}
private void setSameParams(float param) {
for (int i = 0; i < 8; i++) {
radiuses[i] = param;
}
}
/**
* 如果是原始值,则置为0f。
*
* @param pre
* @param next
* @param origin
* @param param
*/
private void setTwoParams(int pre, int next, boolean origin, float param) {
if (origin) {
radiuses[pre] = 0f;
radiuses[next] = 0f;
} else {
radiuses[pre] = param;
radiuses[next] = param;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int width = getWidth();
int height = getHeight();
mLineRect.set(mHalfLineWidth, mHalfLineWidth, (width - mHalfLineWidth), (height - mHalfLineWidth));
mContentRect.set(mLineWidth, mLineWidth, (width - mLineWidth), (height - mLineWidth));
}
@Override
protected void onDraw(Canvas canvas) {
drawRoundRect(canvas);
super.onDraw(canvas);
}
/**
* 1.画圆角矩形
*
* @param canvas
*/
private void drawRoundRect(Canvas canvas) {
Path path = new Path();
path.addRoundRect(mContentRect, radiuses, Path.Direction.CW);
mPaint.setColor(mContentColor);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, mPaint);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mLineColor);
if (!mSolidLine) {
mPaint.setPathEffect(mPathEffect);
path.reset();
}
path.addRoundRect(mLineRect, radiuses, Path.Direction.CW);
canvas.drawPath(path, mPaint);
}
}
<declare-styleable name="ShapeTextView">
<attr name="shape_line_color" format="color" />
<attr name="shape_line_width" format="dimension" />
<attr name="shape_content_color" format="color" />
<attr name="shape_solid_line" format="boolean" />
<attr name="shape_radius" format="dimension" />
<attr name="shape_left_top_radius" format="dimension" />
<attr name="shape_left_bottom_radius" format="dimension" />
<attr name="shape_right_top_radius" format="dimension" />
<attr name="shape_right_bottom_radius" format="dimension" />
</declare-styleable>