效果
1.gif
实现
圆形进度条
<declare-styleable name="CircleProgress">
<attr name="cpRadius" format="dimension" />
<attr name="cpColor" format="color" />
</declare-styleable>
/**
* 圆形进度条
*
* @author gavin.xiong 2017/7/18
*/
public class CircleProgress extends View {
/**
* 半径
*/
private int mRadius;
/**
* 宽
*/
private int mWidth;
/**
* 高
*/
private int mHeight;
/**
* 高
*/
private Paint mPaint;
/**
* 进度(最大100)
*/
private float mProgress = 0;
public CircleProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgress);
mRadius = ta.getDimensionPixelSize(R.styleable.CircleProgress_cpRadius,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 28f, getResources().getDisplayMetrics()));
int color = ta.getColor(R.styleable.CircleProgress_cpColor, 0x40ffffff);
ta.recycle();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
mWidth = specSize;
} else {
mWidth = defaultRadius() * 2;
}
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
mHeight = specSize;
} else {
mHeight = defaultRadius() * 2;
}
setMeasuredDimension(mWidth, mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
if (mProgress < 0 || mProgress > 100) {
return;
}
RectF oval = new RectF(mWidth / 2 - mRadius, mHeight / 2 - mRadius, mWidth / 2 + mRadius, mHeight / 2 + mRadius);
// 根据进度画圆弧 - 反向
canvas.drawArc(oval, mProgress / 100 * 360 - 90, 360 - mProgress / 100 * 360, true, mPaint);
}
/**
* 设置进度 最大值100
*/
public void setProgress(float progress) {
this.mProgress = progress;
postInvalidate();
}
private int defaultRadius() {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 28f, getResources().getDisplayMetrics());
}
}
方形进度条
<declare-styleable name="SquareProgress">
<attr name="spColor" format="color" />
</declare-styleable>
/**
* 方形进度条
*
* @author gavin.xiong 2017/7/22
*/
public class SquareProgress extends View {
private static final String TAG = "SquareProgress";
/**
* 宽
*/
private int mWidth;
/**
* 高
*/
private int mHeight;
/**
* 高
*/
private Paint mPaint;
/**
* 进度(最大100)
*/
private double mProgress = 0;
public SquareProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SquareProgress);
int color = ta.getColor(R.styleable.SquareProgress_spColor, 0x40ffffff);
ta.recycle();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
mWidth = specSize;
} else {
mWidth = defaultLength();
}
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
mHeight = specSize;
} else {
mHeight = defaultLength();
}
setMeasuredDimension(mWidth, mHeight);
}
private int defaultLength() {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 56f, getResources().getDisplayMetrics());
}
@Override
protected void onDraw(Canvas canvas) {
if (mProgress < 0 || mProgress >= 100) {
return;
}
// 偏移角度
double x = mProgress / 100 * 2 * Math.PI;
double ratio = mWidth * 1D / mHeight;
Path path = new Path();
path.moveTo(mWidth / 2, mHeight / 2);
if (mProgress <= 25) {
Log.e(TAG, "第一象限");
if (Math.tan(x) <= ratio) {
Log.e(TAG, "上横边");
path.lineTo(mWidth / 2 + (float) Math.tan(x) * mHeight / 2, 0);
path.lineTo(mWidth, 0);
path.lineTo(mWidth, mHeight);
path.lineTo(0, mHeight);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
} else {
Log.e(TAG, "上竖边");
path.lineTo(mWidth, mHeight / 2 - (float) Math.tan(Math.PI / 2 - x) * mWidth / 2);
path.lineTo(mWidth, mHeight);
path.lineTo(0, mHeight);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
}
} else if (mProgress <= 50) {
Log.e(TAG, "第二象限");
if (Math.tan(x - Math.PI / 2) <= 1 / ratio) {
Log.e(TAG, "下竖边");
path.lineTo(mWidth, mHeight / 2 + (float) Math.tan(x - Math.PI / 2) * mWidth / 2);
path.lineTo(mWidth, mHeight);
path.lineTo(0, mHeight);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
} else {
Log.e(TAG, "下横边");
path.lineTo(mWidth / 2 + (float) Math.tan(Math.PI - x) * mHeight / 2, mHeight);
path.lineTo(0, mHeight);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
}
} else if (mProgress <= 75) {
Log.e(TAG, "第三象限");
if (Math.tan(x - Math.PI) <= ratio) {
Log.e(TAG, "下横边");
path.lineTo(mWidth / 2 - (float) Math.tan(x - Math.PI) * mHeight / 2, mHeight);
path.lineTo(0, mHeight);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
} else {
Log.e(TAG, "下竖边");
path.lineTo(0, mHeight / 2 + (float) Math.tan(Math.PI * 3 / 2 - x) * mWidth / 2);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
}
} else {
Log.e(TAG, "第四象限");
if (Math.tan(x - Math.PI * 3 / 2) <= 1 / ratio) {
Log.e(TAG, "上竖边");
path.lineTo(0, mHeight / 2 - (float) Math.tan(x - Math.PI * 3 / 2) * mWidth / 2);
path.lineTo(0, 0);
path.lineTo(mWidth / 2, 0);
} else {
Log.e(TAG, "上横边");
path.lineTo(mWidth / 2 - (float) Math.tan(Math.PI * 2 - x) * mHeight / 2, 0);
path.lineTo(mWidth / 2, 0);
}
}
path.close();
canvas.drawPath(path, mPaint);
}
/**
* 设置进度 最大值100
*/
public void setProgress(float progress) {
this.mProgress = progress;
postInvalidate();
}
}
网友评论