简单自定义ProgressBar

作者: DongBold | 来源:发表于2016-12-08 11:19 被阅读1338次

    ProgressBar是一个基本的UI控件, 很多地方多会用到, 登录时, 访问加载时, 进行一些耗时的操作的时候, 可以直观的告诉用户当前的进度, 或者告诉用户需要等待, 不然用户还以为死机了呢!

    一些常用的属性

    • max: 进度条的最大值
    • progress: 进度条已完成的进度之
    • progressDrawable: 设置亏到对应的drawable对象
    • indeterminate: 设置不精确显示进度
    • indeterminateDrawable: 设置不显示进度条的Drawable对象
    • indeterminateDuration: 设置不精确显示进度的持续时间
    • secondaryProgress: 设置二级进度条

    先来看一看使用现成的一些进度条样式

        <ProgressBar
            android:id="@+id/progress1"
            style="@android:style/Widget.ProgressBar.Small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
        <ProgressBar
            android:id="@+id/progress2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/progress1"/>
    
        <ProgressBar
            android:id="@+id/progress3"
            style="@android:style/Widget.ProgressBar.Large"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/progress2"/>
    
        <ProgressBar
            android:id="@+id/progress4"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/progress3"
            android:max="100"
            android:progress="18"/>
    
        <ProgressBar
            android:id="@+id/progress5"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/progress4"
            android:layout_marginTop="10dp"
            android:indeterminate="true"
            />
    
        <ImageView
            android:id="@+id/img_pgbar"
            android:layout_below="@id/progress5"
            android:src="@drawable/amin_bgbar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    

    都很丑啊有没有



    所以需要自定义一个



    最后一个是我们自己定义的, 要怎么做呢?
    其实就是用一些图片素材做一个 逐帧动画
    看一下素材:

    然后在drawable目录下创建amin_bgbar.xml文件:

    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                    android:oneshot="false">
        <!--oneshot:是否只展示一遍-->
    
        <item
            android:drawable="@drawable/loading_01"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_02"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_03"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_04"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_05"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_06"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_07"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_08"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_09"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_10"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_11"
            android:duration="200"/>
        <item
            android:drawable="@drawable/loading_12"
            android:duration="200"/>
    
    </animation-list>
    

    oneshot表示是否重复, true表示只播放一次, false表示重复
    duration表示展示该图片的时长
    然后在布局文件创建一个ImageView, src引用这个drawable, 之后再MainActivity中

    private ImageView img_pgbar;
        private AnimationDrawable ad;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            img_pgbar = (ImageView) findViewById(R.id.img_pgbar);
            ad = (AnimationDrawable) img_pgbar.getDrawable();
            img_pgbar.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ad.start();
                }
            }, 100);
        }
    

    不过上面的例子充其量也是一个动画而已, 并不能显示当前进度


    代码

    
    public class CircleProgressBar extends View {
    
        private Paint mBackPaint;
        private Paint mFrontPaint;
        private Paint mTextPaint;
        // 画笔宽度
        private float mStrokeWidth = 50;
        // 画笔的一半宽度
        private float mHalfStrokeWidth = 50 / 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 CircleProgressBar(Context context) {
            this(context, null, 0);
        }
    
        public CircleProgressBar(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CircleProgressBar(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);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mWidth = getRealSize(widthMeasureSpec);
            mHeight = getRealSize(heightMeasureSpec);
            setMeasuredDimension(mWidth, mHeight);
        }
    
        // 计算真实大小
        private 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;
        }
    
        // 设置当前进度
        public void setProgress(int progress) {
            mProgress = progress;
            invalidate();
        }
    
        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);
            }
    
        }
    
        @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;
                // 延迟100毫秒更新
                postInvalidateDelayed(100);
            }
        }
    }
    

    关于使用Canvas绘制图形, 这里又一篇 博客推荐大家看看

    相关文章

      网友评论

        本文标题:简单自定义ProgressBar

        本文链接:https://www.haomeiwen.com/subject/kbzjmttx.html