自定义圆形进度条(旋转进度+百分比)

欢迎大家批评指正

效果如下

转载请注明:https://blog.csdn.net/jinchen_boke/article/details/80546871,谢谢。

代码如下:

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by lenovo on 2018/3/16.
 */

public class CircleProgreessView extends View {

    //控件宽高
    private float mWidth;
    private float mHeight;

    //画笔
    private Paint mPaint;
    //中间的文本
    private String text = "0%";//测试用
    private float strokeWidth = 10f; //圆圈的宽度
    private float textSize = 40f;//中间文本的大小
    private int textColor = Color.RED;//中间文本的颜色
    private int bgCircleColor = Color.GREEN;//背景圆圈的颜色
    private int progressCircleColor = Color.BLUE;//进度圆圈的颜色
    //当前进度
    private int mProgress;

    //旋转的动画
    private ValueAnimator animator;

    public CircleProgreessView(Context context) {
        this(context,null);
    }

    public CircleProgreessView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleProgreessView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        if(null == mPaint){
            mPaint = new Paint();
            mPaint.setAntiAlias(true); //消除锯齿
            mPaint.setTextSize(textSize);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画布移动到控件中央,以控件中心为圆心
        canvas.translate(mWidth/2,mHeight/2);
        //测量文本的宽和高
        Rect textRect = new Rect();
        mPaint.getTextBounds(text,0, text.length(),textRect);
        int textHeight = textRect.height();
        int textWidth = textRect.width();
        //设置为填充样式
        mPaint.setStyle(Paint.Style.FILL);
        //设置中间的文本颜色
        mPaint.setColor(textColor);
        //已经以控件中心为原点,画文本的时候这里传入的位置是文本的左下角的位置,
        //所以要传入-textWidth/2 ,textHeight/2 修正一下
        //画中间的文本
        canvas.drawText(text,-textWidth/2 ,textHeight/2,mPaint);

        //设置 圆圈 样式为空心,这样才显示为圆圈
        mPaint.setStyle(Paint.Style.STROKE);
        //设置 背景圆圈 的颜色
        mPaint.setColor(bgCircleColor);

        //环带宽度,圆宽度,边线宽度
        mPaint.setStrokeWidth(strokeWidth);
        //画 背景圆圈
        canvas.drawCircle(0,0,mHeight/2 - strokeWidth /2,mPaint);


        if(mProgress != 0){
            //画 进度圆圈
            mPaint.setColor(progressCircleColor);
            //画 进度圆圈,因为画弧线的时候,是以弧线的中线到边界,如果用于画圈的矩形去掉 strokeWidth /2
            //那在内切的地方 就会有1/2的弧线是看不到的,所以矩形的四个边要收缩 1/2边线的宽度
            canvas.drawArc(new RectF(
                    -mWidth/2+ strokeWidth /2,
                    -mHeight/2+ strokeWidth /2,
                    mWidth/2- strokeWidth /2,
                    mHeight/2- strokeWidth /2),
                    180,//从左侧开始画,逆时针从右侧旋转180到左侧,开始画
                    360 * mProgress/100f,//进度,转换为度数
                    false,//画出的弧形,不封闭,否则会连接两端的半径进行封闭
                        mPaint);
        }

        //平移位置后恢复
        canvas.restore();

    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }



    /**
     * 设置进度,设置后进度会从0到这个进度,会有一个动画,这个时间也可以传过来
     * @param progress 0-100
     * @param animationTime 动画时间,单位为毫秒
     */
    public void setProgress(int progress, int animationTime){
        //this.mProgress = progress;
        startAnimator(progress,animationTime);
    }
    /**
     * 更新进度,如下载时可以调用这个方法,更新进度,不带动画
     * @param progress 0-100
     */
    public void updateProgress(int progress){
        //this.mProgress = progress;
        startAnimator(progress,0);
    }

    private void startAnimator(int value,int animationTime) {
        if(0 == animationTime){
            mProgress = value;
            text = mProgress+"%";
            invalidate();
        }else {
            if(null != animator && animator.isRunning()){
                animator.cancel();
            }
            animator = ValueAnimator.ofInt(0, value);
            animator.setDuration(animationTime);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    /**
                     * 通过这样一个监听事件,我们就可以获取
                     * ValueAnimator每一步所产生的值。
                     * 通过调用getAnimatedValue()获取到每个时间因子所产生的Value                     * */
                    Integer value = (Integer) animation.getAnimatedValue();
                    mProgress = value;
                    text = mProgress+"%";
                    invalidate();
                }
            });
            animator.start();
        }


    }
}
测试代码如下:
Random random = new Random();
点击更新进度 执行如下方法:
public void order(View view){
 
    int precent = random.nextInt(100);
    if(precent == 0){
        precent =1;
    }

    progressView.setProgress(precent,1000);
    //progressView.updateProgress(precent);
}
 
 



猜你喜欢

转载自blog.csdn.net/jinchen_boke/article/details/80546871