效果图如下:
看到上述view的效果,首先分析view有几部分组成,这里仅做练习,没有做适配。
一。view的组成
1.由不同的扇形
2.各分类的线段
3.各分类的名字
1.绘制不同的扇形,这个比容易,首先要弄清楚0度是从哪个位值开始,android中0角度从x轴开始,顺时针叠加
canvas.drawArc(rectF,180,130,true,paint);
使用deawArc方式,第一个是图形的显示区域,第二个是其实角度,第三个是图形所占用的角度,第四个画笔对象
2.绘制分类上方的线段
这里要据算出每个分类的弧上的中心位置,这里要使用PathMesure 的getPosTan 和 getLength方法,具体代码如下:
mPath.addArc(rectF,180,130);
mMeasure.setPath(mPath, false);
mMeasure.getPosTan(mMeasure.getLength()/2, pos, tan);
Log.e("path",mMeasure.getLength() + " " + pos[0] + " " + pos[1]);
getPostan 方法需要传入图形的长度,两个数组, 因为我们需要获取图形的中点坐标,所以传入长度的一半就可以获取到图形的中点坐标
3.接下来绘制文字
绘制文字比较简单,由上文计算出的坐标,通过适当的加减,来绘制坐标即可
float textWidth = paint.measureText(str[0]);
canvas.drawText(str[0],pos[0]-110 - textWidth-10,pos[1]-20,paint);
二。接下里贴完整代码
public class PieChart extends View
{
private Paint paint;
private Path mPath;
private float[] pos;
private float[] tan;
private PathMeasure mMeasure;
private String[] str = {"Java","php","android","ios"};
public PieChart(Context context, AttributeSet attrs)
{
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
mPath = new Path();
mMeasure = new PathMeasure();
pos = new float[2];
tan = new float[2];
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 综合练习
// 练习内容:使用各种 Canvas.drawXXX() 方法画饼图
RectF rectF = new RectF(200,200,600,600);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(1);
canvas.drawArc(rectF,180,130,true,paint);
mPath.addArc(rectF,180,130);
mMeasure.setPath(mPath, false);
mMeasure.getPosTan(mMeasure.getLength()/2, pos, tan);
Log.e("path",mMeasure.getLength() + " " + pos[0] + " " + pos[1]);
paint.setColor(Color.WHITE);
//canvas.drawCircle(pos[0], pos[1], 10, paint);
canvas.drawLine(pos[0], pos[1],pos[0]-10,pos[1]-20,paint);
canvas.drawLine(pos[0]-10,pos[1]-20,pos[0]-110,pos[1]-20,paint);
paint.setTextSize(30);
float textWidth = paint.measureText(str[0]);
canvas.drawText(str[0],pos[0]-110 - textWidth-10,pos[1]-20,paint);
// paint.setStrokeWidth(50);
// paint.setColor(Color.BLUE);
// canvas.drawPoint(400,400,paint);
paint.setColor(Color.YELLOW);
RectF rectF2 = new RectF(220,220,620,620);
canvas.drawArc(rectF2,310,60,true,paint);
Path path2 = new Path();
path2.addArc(rectF2,310,60);
mMeasure.setPath(path2, false);
mMeasure.getPosTan(mMeasure.getLength()/2, pos, tan);
paint.setColor(Color.WHITE);
//canvas.drawCircle(pos[0], pos[1], 10, paint);
canvas.drawLine(pos[0], pos[1],pos[0]+10,pos[1]-20,paint);
canvas.drawLine(pos[0]+10,pos[1]-20,pos[0]+110,pos[1]-20,paint);
paint.setTextSize(30);
canvas.drawText(str[1],pos[0]+110 + 10 ,pos[1]-20,paint);
Log.e("path2",mMeasure.getLength() + " " + pos[0] + " " + pos[1]);
paint.setColor(Color.BLUE);
canvas.drawArc(rectF2,10,5,true,paint);
paint.setColor(Color.BLACK);
canvas.drawArc(rectF2,15,10,true,paint);
paint.setColor(Color.BLUE);
canvas.drawArc(rectF2,25,5,true,paint);
paint.setColor(Color.WHITE);
canvas.drawArc(rectF2,30,10,true,paint);
paint.setColor(Color.BLUE);
canvas.drawArc(rectF2,40,5,true,paint);
paint.setColor(Color.GREEN);
canvas.drawArc(rectF2,45,60,true,paint);
Path path6 = new Path();
path6.addArc(rectF2,45,60);
mMeasure.setPath(path6, false);
mMeasure.getPosTan(mMeasure.getLength()/2, pos, tan);
paint.setColor(Color.WHITE);
//canvas.drawCircle(pos[0], pos[1], 10, paint);
canvas.drawLine(pos[0], pos[1],pos[0]+10,pos[1]+20,paint);
canvas.drawLine(pos[0]+10,pos[1]+20,pos[0]+110,pos[1]+20,paint);
paint.setTextSize(30);
canvas.drawText(str[3],pos[0]+110+10 ,pos[1]+20,paint);
paint.setColor(Color.BLUE);
canvas.drawArc(rectF2,105,3,true,paint);
paint.setColor(Color.GRAY);
canvas.drawArc(rectF2,108,70,true,paint);
Path path8 = new Path();
path8.addArc(rectF2,108,70);
mMeasure.setPath(path8, false);
mMeasure.getPosTan(mMeasure.getLength()/2, pos, tan);
paint.setColor(Color.WHITE);
//canvas.drawCircle(pos[0], pos[1], 10, paint);
canvas.drawLine(pos[0], pos[1],pos[0]-10,pos[1]+20,paint);
canvas.drawLine(pos[0]-10,pos[1]+20,pos[0]-110,pos[1]+20,paint);
paint.setTextSize(30);
canvas.drawText(str[2],pos[0]-110-paint.measureText(str[2]) - 10 ,pos[1]+20,paint);
}
}