android 画饼图
2019-03-29 本文已影响23人
一个冬季

1、步骤分析
问:画一个圆我们需要什么?
答:一只笔(Paint),这只笔要有颜色(Paint.setColor),需要半径(R),调用canvas.drawArc()方法来画圆
2、涉及到的知识点讲解
我们通过canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)方法来画弧,该方法接受5个参数
RectF oval:画的弧度要在这个矩形里面
startAngle:开始角度
sweepAngle:弧度划过的角度
useCenter:是否与圆心连接(与圆心连接会成扇形)
paint:画笔
onSizeChanged,该方法是是介于onLayout=>onSizeChanged=>onDraw,所以我们会通过该方法获取宽高
数学上的知识点
Math.cos(d),Math.Sin(d),这里的d是弧度,不是角度

我们画的文字要分别在这4个象限里面
3、OK,大概就这样了,我们开始
初始化画笔
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PieView);
textPadding = (int) typedArray.getDimension(R.styleable.PieView_textPadding, getResources().getDimensionPixelOffset(R.dimen.dp_5));//默认的边距
textNumTextSize = (int) typedArray.getDimension(R.styleable.PieView_numTextSize, getResources().getDimensionPixelOffset(R.dimen.sp_12));//文字
centerTextSize = (int) typedArray.getDimension(R.styleable.PieView_numTextSize, getResources().getDimensionPixelOffset(R.dimen.sp_14));//中心文字大小
textCenterColor = typedArray.getColor(R.styleable.PieView_centerTextColor,getResources().getColor(R.color.blue_00AAFF));
mPain = new Paint();
mPain.setTextSize(textNumTextSize);
mPain.setColor(Color.WHITE);
mPain.setStyle(Paint.Style.FILL);
mPain.setAntiAlias(true);
rectF = new RectF();
获取圆的半径,这里-textPadding的目的是为了后面绘制文字,文字是需要在圆的外面
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
pieWidth = w;
pieHieght = h;
radius = Math.min(w, h) / 2 - textPadding;//textPadding文字距离
}
开始绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (pieViewBeans != null) {
float currentAngle = 0f;
canvas.translate(pieWidth / 2, pieHieght / 2);
rectF.set(-radius, -radius, radius, radius);
mPain.setTextSize(textNumTextSize);
for (int i = 0; i < pieViewBeans.size(); i++) {
//绘制弧形
mPain.setColor(pieViewBeans.get(i).getColor());
canvas.drawArc(rectF, currentAngle, pieViewBeans.get(i).getAngle(), true, mPain);
//绘制文字
float angle = currentAngle + pieViewBeans.get(i).getAngle() / 2;
int textRaidus = radius;
//正玄,余弦函数,有正负极之分
float textX = (float) (textRaidus * Math.cos(angle * Math.PI / 180));
float textY = (float) (textRaidus * Math.sin(angle * Math.PI / 180));
String text = pieViewBeans.get(i).getPercenter() + "%";
if (angle >= 0 && angle <= 90) {//第一象限
textY = textY + textPadding / 2;
} else if (angle > 90 && angle <= 180) {//第二象限
textX = textX - textPadding;
textY = textY + textPadding / 2;
} else if (angle > 180 && angle <= 270) {//第三象限
textX = textX - textPadding;
textY = textY - textPadding / 3;
} else {//第四象限
textY = textY - textPadding / 3;
}
canvas.drawText(text, textX, textY, mPain);
currentAngle = currentAngle + pieViewBeans.get(i).getAngle();
}
mPain.setColor(Color.WHITE);
canvas.drawCircle(0, 0, radius / 2, mPain);
//绘制中心文字
float centerTextX = mPain.measureText(defalutStrng) / 2;
mPain.setTextSize(centerTextSize);
mPain.setColor(textCenterColor);
//这里Y轴多加上 textPadding/2的原因是,我计算radius少了textPadding/2
canvas.drawText(defalutStrng, -centerTextX, (mPain.ascent() + mPain.descent()) / 2 + textPadding/2, mPain);
}
}
这里需要多注意一下,正玄,余弦函数,有[-1,1]之间的区分,所以在计算文字的距离的时候,要特别注意