public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
1.oval :指定圆弧的外轮廓矩形区域。
2.startAngle: 圆弧起始角度,单位为度。
3.sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。
4.useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。
5.paint: 绘制圆弧的画板属性,如颜色,是否填充等。
private RectF rectF = new RectF();
private float strokeWidth = 2;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
//获取总宽度,是包含padding值
int width = MeasureSpec.getSize(widthMeasureSpec);
rectF.set(strokeWidth / 2f, strokeWidth / 2f, width - strokeWidth / 2f, MeasureSpec.getSize(heightMeasureSpec) - strokeWidth / 2f);
float radius = width / 2f; // 半径
float angle = (360 - arcAngle) / 2f; // 角度
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// float startAngle = 270 - arcAngle / 2f;
float startAngle = 0;
float finishedSweepAngle = progress / (float) getMax() * arcAngle;
float finishedStartAngle = startAngle;
if(progress == 0) finishedStartAngle = 0.01f;
paint.setColor(unfinishedStrokeColor);
// canvas.drawArc(rectF, startAngle, arcAngle, false, paint); // 画出最原始的圆弧
canvas.drawArc(rectF, startAngle, 360, false, paint); // 画出最原始的圆弧
paint.setColor(finishedStrokeColor);
/**
* 参数1 指定圆弧的外轮廓矩形区域。
* 参数2 圆弧起始角度,单位为度
* 参数3 圆弧扫过的角度,顺时针方向,单位为度。
* 参数4 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。
*/
canvas.drawArc(rectF, finishedStartAngle, finishedSweepAngle, false, paint); // 画出进度走过的圆弧
}
上面是从0开始绘制的,进度默认设置了20,效果见下图;
从上图可以看到,画圆弧的时候0度正好对应3点整点。
画一个开口的圆弧(一个圆的80%)
public class ArcOProgress extends View {
private Paint paint;
private float endArc = 360 * 0.8f;
private RectF rect = new RectF();
private int progress = 20; // 默认的进度
private float strokeWidth; // 画笔宽度
public ArcOProgress(Context context) {
super(context);
initPaint();
}
public ArcOProgress(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public ArcOProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(Utils.dp2px(getResources(),4));
paint.setDither(true);
paint.setStrokeCap(Paint.Cap.ROUND);
strokeWidth = Utils.dp2px(getResources(),4);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获取总宽度
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
// 获取总高度
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
rect.set(strokeWidth/2, strokeWidth/2, sizeWidth - strokeWidth/2, sizeHeight - strokeWidth/2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float startArc = 270 - endArc / 2f;
float currentProgress = progress / (float) 100 * endArc;
paint.setColor(Color.parseColor("#ffbbcc"));
canvas.drawArc(rect,startArc,endArc,false,paint);
paint.setColor(Color.GREEN);
canvas.drawArc(rect,startArc,currentProgress,false,paint);
}
@Override
public void invalidate() {
initPaint();
super.invalidate();
}
}
效果图:
加入绘制文字:
public class ArcOProgress extends View {
private Paint paint; // 圆弧的画笔
private float endArc = 360 * 0.8f; // 圆弧的总弧度
private RectF rect = new RectF();
private int progress = 20; // 默认的进度
private float strokeWidth; // 画笔宽度
private Paint textPaint; // 绘制文字
private int sizeWidth; // 控件的宽度
private int sizeHeight; // 控件高度
private Paint textBottomPaint; // 圆弧底部的文字绘制画笔
public ArcOProgress(Context context) {
super(context);
initPaint();
}
public ArcOProgress(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public ArcOProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(Utils.dp2px(getResources(),4));
paint.setDither(true);
paint.setStrokeCap(Paint.Cap.ROUND);
strokeWidth = Utils.dp2px(getResources(),4);
textPaint = new Paint();
textPaint.setTextSize(50);
textPaint.setAntiAlias(true);
textPaint.setColor(Color.RED);
textPaint.setStrokeWidth(strokeWidth);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextAlign(Paint.Align.CENTER);
textBottomPaint = new Paint();
textBottomPaint.setStyle(Paint.Style.FILL);
textBottomPaint.setTextSize(70);
textBottomPaint.setAntiAlias(true);
// textBottomPaint.setDither(true);
textBottomPaint.setColor(Color.BLUE);
textBottomPaint.setStrokeWidth(strokeWidth);
textBottomPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获取总宽度
sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
// 获取总高度
sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
rect.set(strokeWidth/2, strokeWidth/2, sizeWidth - strokeWidth/2, sizeHeight - strokeWidth/2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float startArc = 270 - endArc / 2f;
float currentProgress = progress / (float) 100 * endArc;
paint.setColor(Color.parseColor("#ffbbcc"));
canvas.drawArc(rect,startArc,endArc,false,paint);
paint.setColor(Color.GREEN);
canvas.drawArc(rect,startArc,currentProgress,false,paint);
float baseLine = (getHeight() - (textPaint.descent() + textPaint.ascent())) / 2.0f;
canvas.drawText("爱奇艺%",sizeWidth/2,baseLine,textPaint);
float baseLineBottom = getHeight() + ((textBottomPaint.descent() + textBottomPaint.ascent()) / 2.0f);
// float baseLineBottom = getHeight();
canvas.drawText("爱奇艺",sizeWidth/2,baseLineBottom,textBottomPaint);
}
@Override
public void invalidate() {
initPaint();
super.invalidate();
}
}
/**
* DP、SP 转换为 PX 的工具类
*/
public class Util {
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}