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