正在学习中,大神请指教
最近需要双环形进度条,就长下面这样:
(为毛贴图这么不清晰啊...)
于是,就练习了下简单的自定义view。
虽然很简单,但是纪录一下。
代码如下,注释很详细
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* 双环进度条
*/
public class ArcProgressView extends View {
public ArcProgressView(Context context) {
this(context, null);
}
public ArcProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private Thread animThread; //动画线程
//画笔
private Paint paint;
//背景色,外环颜色,内环颜色
private int bgColor = 0x00000000, outerColor = 0xff29b6f6, innerColor = 0xff00a0e8;
//环的宽度
private int strokeWidth = 8;
//内环占外环的比例
private float percent = 0f;
//外环进度,内环进度(=360时没有动画,此处外环无动画效果)
private float outerAngle = 360, innerAngle;
public void setParams(float percent) {
setParams(bgColor, outerColor, innerColor, strokeWidth, percent);
}
public void setParams(int innerColor, int strokeWidth, float percent) {
setParams(bgColor, outerColor, innerColor, strokeWidth, percent);
}
public void setParams(int bgColor, int outerColor, int innerColor, int strokeWidth, float percent) {
this.bgColor = bgColor;
this.outerColor = outerColor;
this.innerColor = innerColor;
this.strokeWidth = strokeWidth;
this.percent = Math.min(percent, 1.0f);
resetParam(); //重置参数
postInvalidate();
}
private void resetParam() {
animThread = null; //动画县城置空
innerAngle = 0; //内环初始值为0
paint = getPaint(); //重置画笔
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (paint == null) {
return;
}
//动画线程不为空&内环终值不为0时,启动动画
if (animThread == null && percent > 0) {
animThread = getThread();
animThread.start();
} else {
//画背景色
canvas.drawColor(bgColor);
//获取环的直径
int maxWidth = Math.min(getWidth(), getHeight());
//获取环的偏移量
int xDistance = 0, yDistance = 0;
if (getWidth() > getHeight()) {
xDistance = (getWidth() - getHeight()) / 2;
} else if (getWidth() < getHeight()) {
yDistance = (getHeight() - getWidth()) / 2;
}
//外环
if (outerAngle <= 360) {
RectF ovalOuter = new RectF();//RectF对象
paint.setColor(outerColor);
//设置环到矩形区域的left\top\right\bottom的距离
ovalOuter.set(xDistance + strokeWidth, yDistance + strokeWidth, maxWidth - strokeWidth + xDistance, maxWidth - strokeWidth + yDistance);
//画环:1.环形所占矩形区域;2.起始角度;3.环扫过的角度,顺时针;4.画笔
canvas.drawArc(ovalOuter, 90, outerAngle, false, paint); //绘制圆弧
}
//内环
if (innerAngle <= 360 * percent) {
RectF ovalInner = new RectF(); //RectF对象
paint.setColor(innerColor);
//设置内环区域
ovalInner.set(xDistance + strokeWidth * 1.8f, yDistance + strokeWidth * 1.8f, maxWidth - strokeWidth * 1.8f + xDistance, maxWidth - strokeWidth * 1.8f + yDistance);
canvas.drawArc(ovalInner, 90, innerAngle, false, paint); //绘制圆弧
if (onProgressListener != null) {
onProgressListener.onProgress(innerAngle / (360 * percent));
}
}
}
}
private Paint getPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Paint.Style.STROKE);
return paint;
}
private Thread getThread() {
return new Thread(new Runnable() {
@Override
public void run() {
//外环、内环步长
int outerStep = 10, innerStep = 8;
//是否过界
while ((outerAngle < 360) || (innerAngle < 360 * percent)) {
outerAngle = Math.min(outerAngle + outerStep, 360);
innerAngle = Math.min(innerAngle + innerStep, 360 * percent);
postInvalidate();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
@Override
protected void onDetachedFromWindow() {
outerAngle = innerAngle = 99999; //退出循环
super.onDetachedFromWindow();
}
/**
* listener
*/
private OnProgressListener onProgressListener;
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
public interface OnProgressListener {
/**
* 可根据画环的进度更新环内的数字
*
* @param progress
*/
void onProgress(float progress);
}
}
学无止境啊,加油加油~