学习|自定义圆形progressbar(包含进度动画效果)

【学习|自定义圆形progressbar(包含进度动画效果)】效果图敬上:)

attrs文件:
< resources>
< declare-styleable name=”CircleProgressBarStyle”>
< attr name=”circleColor” format=”color”/>
< attr name=”circleProgressColor” format=”color”/>
< attr name=”progressWidth” format=”float”/>
< attr name=”progress” format=”integer”/>
< attr name=”max” format=”integer”/>
< attr name=”progressPadding” format=”integer”/>
< attr name=”animation” format=”boolean”/>
< attr name=”style”>
< enum name=”STROKE” value=https://www.it610.com/article/”0”/>
< enum name=”FILL” value=https://www.it610.com/article/”1”/>
< /attr>
< /declare-styleable>
< /resources>
xml文件:记着加 xmlns:progress=”http://schemas.android.com/apk/res-auto”

< com.test.ffmpeg.CircleProgressBar android:id="@+id/CircleProgressBar" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" progress:circleColor="@color/white" progress:circleProgressColor="@color/colorAccent" progress:progressWidth="10" progress:progressPadding="15" progress:progress="50" progress:max="100" progress:animation="true" progress:style="FILL"/>

CircleProgressBar:
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * 自定义圆形progressbar */public class CircleProgressBar extends View { /** * 画笔 */ private Paint mPaint; /** * 实心圆颜色 */ private int CircleColor; /** * 圆环颜色 */ private int CircleProgressColor; /** * 圆环宽度 */ private float CircleProgressWidth; /** * 实心圆与环间的距离 */ private int ProgressPadding; /** * 最大进度 */ private int ProgressMax; /** * 进度的风格,是否绘画内部实心圆 */ private int style; /** * 当前进度 */ private int progress; /** * 显示时是否需要动画效果 */ private boolean animation; /** * 进度动画更新次数 */ private int speed = 100; //这里修改的话每隔10ms处也应修该,个人感觉这个值正好! private double progress_=0; //临时存储double类型格式的进度 private int temporaryProgress=0; //临时存放记录的progress private double temporary=0; private boolean isFirst=true; //是否是第一次绘制 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if(speed>=0) { speed--; progress_ = progress_ + temporary; if(progress_>=temporaryProgress){ progress=temporaryProgress; }else { progress= (int) progress_; } setProgress(progress); mHandler.sendEmptyMessageDelayed(1, 10); //每隔10ms执行一次 }else { mHandler.removeMessages(1); }} }; public CircleProgressBar(Context context) { this(context, null); }public CircleProgressBar(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); //!!! }public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); //获取自定义属性值 TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBarStyle); CircleColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleColor, Color.WHITE); CircleProgressColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleProgressColor, Color.BLUE); CircleProgressWidth = mTypedArray.getFloat(R.styleable.CircleProgressBarStyle_progressWidth, 5); ProgressMax = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_max, 100); style = mTypedArray.getInt(R.styleable.CircleProgressBarStyle_style, 1); progress = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progress, 60); ProgressPadding = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progressPadding, 0); animation = mTypedArray.getBoolean(R.styleable.CircleProgressBarStyle_animation, false); mTypedArray.recycle(); }@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //开始绘制 内部实心圆 int circle_x = getWidth() / 2; //获取圆心坐标 int radius = (int) (circle_x - CircleProgressWidth - ProgressPadding); int prgress_radius = (int) (circle_x - CircleProgressWidth); if (style == 1) {//判断是否绘画内部实心圆 mPaint.setColor(CircleColor); //画笔颜色 mPaint.setStyle(Paint.Style.FILL); //实心 mPaint.setAntiAlias(true); //消除锯齿 canvas.drawCircle(circle_x, circle_x, radius, mPaint); } //progressbar进度条(扇形环) RectF rectF = new RectF(circle_x - prgress_radius, circle_x - prgress_radius, circle_x + prgress_radius, circle_x + prgress_radius); mPaint.setColor(CircleProgressColor); mPaint.setStyle(Paint.Style.STROKE); //空心 mPaint.setStrokeWidth(CircleProgressWidth); //圆环宽度 mPaint.setAntiAlias(true); //消除锯齿 if (animation && isFirst) { isFirst=false; temporary=(double) progress/speed; //设置每次progress增量值 Log.e("增量",""+temporary); temporaryProgress=progress; //记录 progress=0; //归0 mHandler.sendEmptyMessage(1); } canvas.drawArc(rectF, -90, 360 * progress / ProgressMax, false, mPaint); }public int getCircleColor() { return CircleColor; }public void setCircleColor(int circleColor) { CircleColor = circleColor; }public int getCircleProgressColor() { return CircleProgressColor; }public void setCircleProgressColor(int circleProgressColor) { CircleProgressColor = circleProgressColor; }public float getCircleProgressWidth() { return CircleProgressWidth; }public void setCircleProgressWidth(float circleProgressWidth) { CircleProgressWidth = circleProgressWidth; }public int getProgressPadding() { return ProgressPadding; }public void setProgressPadding(int progressPadding) { ProgressPadding = progressPadding; }public int getProgressMax() { return ProgressMax; }public void setProgressMax(int progressMax) { if (progressMax > 0) ProgressMax = progressMax; }public int getStyle() { return style; }public void setStyle(int style) { this.style = style; }public synchronized int getProgress() { return progress; }/** * 加个锁,防止属性animation和外部同时调用该方法异常 * * @param progress */ public synchronized void setProgress(int progress) { if (progress > 0) this.progress = progress > ProgressMax ? ProgressMax : progress; postInvalidate(); } public boolean isAnimation() { return animation; }public void setAnimation(boolean animation) { this.animation = animation; } }

    推荐阅读