【学习|自定义圆形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;
}
}
推荐阅读
- 数组的排序算法
- 学习|Python学习心得,小白初学工具推荐
- 属性动画 Property Animation(上手篇)
- Android自定义View之滑杆内部带数字的SeekBar
- jQuery---用jq实现控件的显示和隐藏
- 使一个布局中的所有事件失效
- 自定义view|android自定义圆弧进度条,可拖拽的progressBar
- android|自定义ProgressBar的样式失效
- 学习|python3打印菱形(测试过)