素材巴巴 > 程序开发 >

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

程序开发 2023-09-08 13:29:46

欢迎大家批评指正

效果如下

转载请注明: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);
 }
 
 




标签:

上一篇: 前端学习笔记之rem适配布局 3.28 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。