最近项目有一个需求,要在首页显示三个环形饼状图,要求可以显示比例大小,中间显示文本部分,并且需要可以自定义颜色。设计图如下:
思路:
绘制一个带百分比的圆环,一共分了四个部分:
1.背景圆(就是底图圆)
2.默认圆环
3.绘制的圆环(就是比例圆环)
4.中心文字
下面我们开始进行绘制,先准备四支画笔, 设置画笔相应的属性;
private Paint roundColorPaint;//外圆画笔
private Paint mCirclePaint;//中心园的画笔
private Paint mTextPaint;//文字的画笔
private Paint mArcPaint;//外圆环的画笔
中间文本框字体大小,颜色也需要进行定义,
private int mTextSize;//字体大小
private int mTextColor;//字体颜色
private String mTopText = "";//第一行文本
private String mBotomText = "";//第二行文本
onMesure()方法里进行测量宽高,因为宽高一样,只需要测量一次宽即可,高等于宽。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec), measure(widthMeasureSpec));
//设置圆心坐标
mCircleX = getMeasuredWidth() / 2;
mCircleY = getMeasuredHeight() / 2;
//如果半径大于圆心横坐标,需要手动缩小半径的值,否则就画到外面去了
if (mRadius > mCircleX) {
//设置半径大小为圆心横坐标到原点的距离
mRadius = mCircleX;
mRadius = (int) (mCircleX - 0.075 * mRadius);
//因为半径改变了,所以要重新设置一下字体宽度
mTextPaint.setStrokeWidth((float) (0.025 * mRadius));
//重新设置字号
mTextPaint.setTextSize(mRadius / 2);
//重新设置外圆环宽度
mArcPaint.setStrokeWidth((float) (0.075 * mRadius));
//重新获得字号大小
mTextSize = (int) mTextPaint.getTextSize();
}
//画中心园的外接矩形,用来画圆环用
mArcRectF = new RectF(mCircleX - mRadius, mCircleY - mRadius, mCircleX + mRadius, mCircleY + mRadius);
}
然后,重写onDraw()
方法,进行绘制
//开始画中间圆、文字和外圆环
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画中间圆
canvas.drawCircle(mCircleX, mCircleY, mRadius, mCirclePaint);
//画圆环
roundColorPaint.setStyle(Paint.Style.STROKE);
//设置外圆环的宽度(默认灰色的圆环)
roundColorPaint.setStrokeWidth((float) (0.075 * mRadius));
canvas.drawCircle(mCircleX, mCircleY, mRadius, roundColorPaint);
//动态绘制红色的圆环
canvas.drawArc(mArcRectF, mStartSweepValue, mCurrentAngle, false, mArcPaint);
// 再使用下面的setTargetPercent方法获取数据动态画圆
//文本自动换行
canvas.drawText(mTopText, mCircleX, mCircleY - mTextSize / 2, mTextPaint); //坐标以控件左上角为原点
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float baseline = fm.descent - fm.ascent;//由于系统基于字体的底部来绘制文本,所有需要加上字体的高度。
// mCircleY +baseline + fm.leading; //添加字体行间距
canvas.drawText(mBotomText, mCircleX, mCircleY + baseline - mTextSize / 2 + fm.leading, mTextPaint); //坐标以控件左上角为原点
//判断当前百分比是否小于设置目标的百分比
if (mCurrentPercent < mTargetPercent) {
if (mTargetPercent - mCurrentPercent <= 1.0) {
double d = mTargetPercent - mCurrentPercent;
mCurrentPercent += d;
mCurrentAngle += d * 3.6;
} else {
//当前百分比+0.1
mCurrentPercent += 1.0;
//当前角度+360
mCurrentAngle += 3.6;
}
//每1ms重画一次
postInvalidateDelayed(1);
}
}
至此带比例的圆环就绘制完成了,效果图如下:
希望可以帮助到大家。