Android ProgressBar 自定义圆环进度条

Android 系统自带的 ProgressBar 几乎都不能满足我们的日常开发,导致我们在开发的时候经常要自己定一个进度条

本章节我们就来实现最常见的圆环进度条,先来看看最后的效果


  1. 创建一个 空的 Android 项目 cn.twle.android.ProgressBarCustom

  2. 自定义一个 View 类 RingProgressBar.java

    package cn.twle.android.progressbarcustom;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class RingProgressBar extends View {
    
        private Paint mBackPaint;
        private Paint mFrontPaint;
        private Paint mTextPaint;
        private float mStrokeWidth = 50;
        private float mHalfStrokeWidth = mStrokeWidth / 2;
        private float mRadius = 200;
        private RectF mRect;
        private int mProgress = 0;
        //目标值,想改多少就改多少
        private int mTargetProgress = 90;
        private int mMax = 100;
        private int mWidth;
        private int mHeight;
    
        public RingProgressBar(Context context) {
            super(context);
            init();
        }
    
        public RingProgressBar(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public RingProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        //完成相关参数初始化
        private void init() {
            mBackPaint = new Paint();
            mBackPaint.setColor(Color.WHITE);
            mBackPaint.setAntiAlias(true);
            mBackPaint.setStyle(Paint.Style.STROKE);
            mBackPaint.setStrokeWidth(mStrokeWidth);
    
            mFrontPaint = new Paint();
            mFrontPaint.setColor(Color.GREEN);
            mFrontPaint.setAntiAlias(true);
            mFrontPaint.setStyle(Paint.Style.STROKE);
            mFrontPaint.setStrokeWidth(mStrokeWidth);
    
            mTextPaint = new Paint();
            mTextPaint.setColor(Color.GREEN);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextSize(80);
            mTextPaint.setTextAlign(Paint.Align.CENTER);
        }
    
        // 重写测量大小的 onMeasure 方法
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mWidth = getRealSize(widthMeasureSpec);
            mHeight = getRealSize(heightMeasureSpec);
            setMeasuredDimension(mWidth, mHeight);
    
        }
    
        // 重写绘制 View 的核心方法 onDraw()
        @Override
        protected void onDraw(Canvas canvas) {
            initRect();
            float angle = mProgress / (float) mMax * 360;
            canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mBackPaint);
            canvas.drawArc(mRect, -90, angle, false, mFrontPaint);
            canvas.drawText(mProgress + "%", mWidth / 2 + mHalfStrokeWidth, mHeight / 2 + mHalfStrokeWidth, mTextPaint);
            if (mProgress < mTargetProgress) {
                mProgress += 1;
                invalidate();
            }
    
        }
    
        public int getRealSize(int measureSpec) {
            int result = 1;
            int mode = MeasureSpec.getMode(measureSpec);
            int size = MeasureSpec.getSize(measureSpec);
    
            if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) {
                //自己计算
                result = (int) (mRadius * 2 + mStrokeWidth);
            } else {
                result = size;
            }
    
            return result;
        }
    
        private void initRect() {
            if (mRect == null) {
                mRect = new RectF();
                int viewSize = (int) (mRadius * 2);
                int left = (mWidth - viewSize) / 2;
                int top = (mHeight - viewSize) / 2;
                int right = left + viewSize;
                int bottom = top + viewSize;
                mRect.set(left, top, right, bottom);
            }
        }
    
    }
    
  3. 然后修改 activity_main.xml 添加我们的 RingProgressBar

    <com.jay.progressbardemo.CirclePgBar
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    

参考文档

官方 API 文档: ProgressBar

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.