View-Draw-圓角矩形Loading

實現(xiàn)說明

1:控件的寬高比2:1
2:圓角矩形的每個角對應的進度是10
3:圓角矩形的每個寬邊對應的進度是10
4:圓角矩形的的每個長邊對應的進度是20


效果圖

Video_20200408_122835_322.gif
img

實現(xiàn)

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;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 1.xcode5和xcode7區(qū)別 1.xcode7沒有Frameworks文件夾,xcode7內(nèi)部會自動幫你導入...
    彼岸的黑色曼陀羅閱讀 575評論 0 2
  • 丁凡峻寒假日記<炸署片>>
    和爸媽一起研學閱讀 125評論 0 0
  • 創(chuàng)建一個數(shù)據(jù)庫,將后臺寫好的數(shù)據(jù)庫導入,在編碼的時候,需要將AppID和AppSecret修改為自己的配置信息, ...
    Tz1314閱讀 394評論 1 0
  • 弄不清楚從什么時候開始,每到年關,都要掛彩燈。這個城市,在我小時候,它是縣級zf,影響深的是小時候父親帶我去看病,...
    蟬翼呵呵閱讀 347評論 1 3
  • 大概是從四年級開始,就由我負責我跟我弟弟的早餐了。 那個時候,我每天六點多就起床了。一般是我會煮兩塊面加兩個雞蛋,...
    喵欣人的生活觀閱讀 522評論 0 2

友情鏈接更多精彩內(nèi)容