package com.soling.sosystemui.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.soling.sosystemui.R;
public class RoundViewGroup extends ConstraintLayout {
protected static final String TAG = "RoundConstraintLayout";
private Path mPath = new Path();
private RectF mRectF = new RectF();
private Paint mPaint = new Paint();
private int mWidth, mHeight;
private int mLeftTopCornerRadius = 20;
private int mLeftBottomCornerRadius = 20;
private int mRightTopCornerRadius = 20;
private int mRightBottomCornerRadius = 20;
public RoundViewGroup(Context context) {
super(context);
}
public RoundViewGroup(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public RoundViewGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void dispatchDraw(Canvas canvas) {
mWidth = getWidth();
mHeight = getHeight();
drawLayer(canvas);
super.dispatchDraw(canvas);
drawPath(canvas);
}
protected void drawPath(Canvas canvas) {
resetPaint();
drawTopLeft(canvas);
drawTopRight(canvas);
drawBottomLeft(canvas);
drawBottomRight(canvas);
mPaint.setXfermode(null);
canvas.restore();
}
protected void drawLayer(Canvas canvas) {
canvas.saveLayer(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), mPaint, Canvas.ALL_SAVE_FLAG);
}
protected void drawStroke(Canvas canvas) {
}
protected Path getStrokePath() {
mPath.reset();
mPath.moveTo(mLeftTopCornerRadius + getStrokeOffset(), getStrokeOffset());
if (mLeftTopCornerRadius > 0) {
mRectF.set(getStrokeOffset(), getStrokeOffset(), mLeftTopCornerRadius * 2, mLeftTopCornerRadius * 2);
mPath.arcTo(mRectF, -90, -90);
}
mPath.lineTo(getStrokeOffset(), mHeight - mLeftBottomCornerRadius - getStrokeOffset());
if (mLeftBottomCornerRadius > 0) {
mRectF.set(getStrokeOffset(), mHeight - 2 * mLeftBottomCornerRadius, mLeftBottomCornerRadius * 2, mHeight - getStrokeOffset());
mPath.arcTo(mRectF, 180, -90);
}
mPath.lineTo(mWidth - mRightBottomCornerRadius - getStrokeOffset(), mHeight - getStrokeOffset());
if (mRightBottomCornerRadius > 0) {
mRectF.set(mWidth - 2 * mRightBottomCornerRadius, mHeight - 2 * mRightBottomCornerRadius, mWidth - getStrokeOffset(), mHeight - getStrokeOffset());
mPath.arcTo(mRectF, 90, -90);
}
mPath.lineTo(mWidth - getStrokeOffset(), mRightTopCornerRadius + getStrokeOffset());
if (mRightTopCornerRadius > 0) {
mRectF.set(mWidth - 2 * mRightTopCornerRadius, getStrokeOffset(), mWidth - getStrokeOffset(), 2 * mRightTopCornerRadius);
mPath.arcTo(mRectF, 0, -90);
}
mPath.close();
return mPath;
}
protected float getStrokeOffset() {
return 0.5f;
}
protected void drawTopLeft(Canvas canvas) {
if (mLeftTopCornerRadius > 0) {
mPath.reset();
mPath.moveTo(0, mLeftTopCornerRadius);
mPath.lineTo(0, 0);
mPath.lineTo(mLeftTopCornerRadius, 0);
mRectF.set(0, 0, mLeftTopCornerRadius * 2, mLeftTopCornerRadius * 2);
mPath.arcTo(mRectF, -90, -90);
mPath.close();
canvas.drawPath(mPath, mPaint);
}
}
protected void drawTopRight(Canvas canvas) {
if (mRightTopCornerRadius > 0) {
mPath.reset();
mPath.moveTo(mWidth - mRightTopCornerRadius, 0);
mPath.lineTo(mWidth, 0);
mPath.lineTo(mWidth, mRightTopCornerRadius);
mRectF.set(mWidth - 2 * mRightTopCornerRadius, 0, mWidth, mRightTopCornerRadius * 2);
mPath.arcTo(mRectF, 0, -90);
mPath.close();
canvas.drawPath(mPath, mPaint);
}
}
protected void drawBottomLeft(Canvas canvas) {
if (mLeftBottomCornerRadius > 0) {
mPath.reset();
mPath.moveTo(0, mHeight - mLeftBottomCornerRadius);
mPath.lineTo(0, mHeight);
mPath.lineTo(mLeftBottomCornerRadius, mHeight);
mRectF.set(0, mHeight - 2 * mLeftBottomCornerRadius, mLeftBottomCornerRadius * 2, mHeight);
mPath.arcTo(mRectF, 90, 90);
mPath.close();
canvas.drawPath(mPath, mPaint);
}
}
protected void drawBottomRight(Canvas canvas) {
if (mRightBottomCornerRadius > 0) {
mPath.reset();
mPath.moveTo(mWidth - mRightBottomCornerRadius, mHeight);
mPath.lineTo(mWidth, mHeight);
mPath.lineTo(mWidth, mHeight - mRightBottomCornerRadius);
mRectF.set(mWidth - 2 * mRightBottomCornerRadius, mHeight - 2 * mRightBottomCornerRadius, mWidth, mHeight);
mPath.arcTo(mRectF, 0, 90);
mPath.close();
canvas.drawPath(mPath, mPaint);
}
}
protected void resetPaint() {
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
}