自定义圆形进度条(旋转进度 百分比)
程序开发
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
下一篇:
相关文章
-
无相关信息