View-Draw-圆角矩形Loading

实现说明

【View-Draw-圆角矩形Loading】1:控件的宽高比2:1
2:圆角矩形的每个角对应的进度是10
3:圆角矩形的每个宽边对应的进度是10
4:圆角矩形的的每个长边对应的进度是20
效果图
Video_20200408_122835_322.gif img 实现
public class RoundRectLoadingView extends View { private static final int MAX_PROCESS = 100; private static final int MIN_PROCESS = 0; //圆角矩形的4个圆弧对应的半径 private int mRadius = 50; //每一个process所对应的时间 private int mProcessTime = 25; //当前进度 private int mProcess; //圆角矩形loading 的显示范围 private int mLeft; private int mTop; private int mRight; private int mBottom; //中间进度字体的基于基线的偏移量 private float mTextOffsetY; //loading框的 path private Path mLoadingpath = new Path(); private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public RoundRectLoadingView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); }@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mLeft = 70; mTop = 35; mRight = w - mLeft; mBottom = h - 35; }@Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.parseColor("#55ff0000")); drawFrame(canvas); drawText(canvas); }private void init() { mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(Utils.dp2px(5)); mPaint.setColor(Color.BLACK); mTextPaint.setStyle(Paint.Style.STROKE); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setTextSize(Utils.dp2px(35)); mTextPaint.setColor(Color.WHITE); Paint.FontMetrics fm = mTextPaint.getFontMetrics(); mTextOffsetY = -(fm.top + fm.bottom) / 2.0F; }private void drawText(Canvas canvas) { String text = String.format(Locale.getDefault(), "%d%s", mProcess, "%"); canvas.drawText(text, getWidth() / 2, getHeight() / 2 + mTextOffsetY, mTextPaint); }private void drawFrame(Canvas canvas) {int widthHalf = (mRight - mLeft) / 2; int cenerX = mLeft + widthHalf; float rate; mLoadingpath.reset(); mLoadingpath.moveTo(cenerX, mTop); //进度0-10 if (mProcess > 0) { rate = getRate(10); mLoadingpath.lineTo(cenerX + (widthHalf - mRadius) * rate, mTop); }//进度11-20 if (mProcess > 10) { rate = getRate(20); mLoadingpath.addArc(mRight - mRadius * 2, mTop, mRight, mTop + mRadius * 2, -90, 90 * rate); }//进度21-00 if (mProcess > 20) { rate = getRate(30); int startY = mTop + mRadius; int endY = mBottom - mRadius; float lineToY = startY + (endY - startY) * rate; mLoadingpath.lineTo(mRight, lineToY); }//进度31-40 if (mProcess > 30) { rate = getRate(40); mLoadingpath.addArc(mRight - mRadius * 2, mBottom - mRadius * 2, mRight, mBottom, 0, 90 * rate); }//进度41-50 if (mProcess > 40) { rate = getRate(50); mLoadingpath.lineTo(mRight - mRadius - (widthHalf - mRadius) * rate, mBottom); }//进度51-60 if (mProcess > 50) { rate = getRate(60); mLoadingpath.lineTo(cenerX - (widthHalf - mRadius) * rate, mBottom); }//进度61-70 if (mProcess > 60) { rate = getRate(70); mLoadingpath.addArc(mLeft, mBottom - mRadius * 2, mLeft + mRadius * 2, mBottom, 90, 90 * rate); }//进度71-80 if (mProcess > 70) { rate = getRate(80); int startY = mTop + mRadius; int endY = mBottom - mRadius; float lineToY = endY - (endY - startY) * rate; mLoadingpath.lineTo(mLeft, lineToY); }//进度81-90 if (mProcess > 80) { rate = getRate(90); mLoadingpath.addArc(mLeft, mTop, mLeft + mRadius * 2, mTop + mRadius * 2, 180, 90 * rate); }//进度91-100 if (mProcess > 90) { rate = getRate(100); mLoadingpath.lineTo(mLeft + mRadius + (widthHalf - mRadius) * rate, mTop); }canvas.drawPath(mLoadingpath, mPaint); }public int getProcess() { return mProcess; }public void setProcess(int process) { if (!isLegalProcess(process)) { return; } mProcess = process; postInvalidate(); }public void startAni(int process) { if (!isLegalProcess(process)) { return; }ObjectAnimator animator = ObjectAnimator.ofInt(this, "process", 0, process); animator.setDuration(process * mProcessTime); animator.setInterpolator(new LinearInterpolator()); animator.start(); }private boolean isLegalProcess(int process) { if (process < MIN_PROCESS || process > MAX_PROCESS) { return false; } return true; }private float getRate(int process) { int rate = mProcess > process ? 0 : process - mProcess; return 1.0F - rate / 10F; } }

    推荐阅读