彩色圆环统计图
事先说明:
如果对View的绘制不熟悉的话,可以先查阅资料绘制简单的几何图形,再来阅读本篇文章
如果是对View刚入门的,可以先从我最简单的View学起:简单实现边缘凹凸电子票效果
更多有趣的View尽在我的CSDN博客:http://blog.csdn.net/qq_30379689
效果图:
步骤一:分析变量信息
//-------------必须给的数据相关------------- private String[] str = new String[]{"一年级", "二年级", "三年级", "四年级", "五年级", "六年级"}; //分配比例大小,总比例大小为100 private int[] strPercent = new int[]{10, 25, 18, 41, 2, 5}; //圆的直径 private float mRadius = 300; //圆的粗细 private float mStrokeWidth = 40; //文字大小 private int textSize = 20; //-------------画笔相关------------- //圆环的画笔 private Paint cyclePaint; //文字的画笔 private Paint textPaint; //标注的画笔 private Paint labelPaint; //-------------颜色相关------------- //边框颜色和标注颜色 private int[] mColor = new int[]{0xFFF06292, 0xFF9575CD, 0xFFE57373, 0xFF4FC3F7, 0xFFFFF176, 0xFF81C784}; //文字颜色 private int textColor = 0xFF000000; //-------------View相关------------- //View自身的宽和高 private int mHeight; private int mWidth;圆的粗细:圆环的大小。
标注:文字前面的圆点。
分配比例大小:由于需要计算圆环扫过的角度,计算方法使用:(比例/100)*360度,用百分比算出360度占用了多少,由于比例/100的结果一直是0,所以换一种方法:(比例*360度)/100,先乘后除,但是这样会导致没办法获得100/100的值,所以我们分配比例大小的总和为101.
步骤二:获取View的宽和高
public MyChatView(Context context) { super(context); } public MyChatView(Context context, AttributeSet attrs) { super(context, attrs); } public MyChatView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; }
步骤三:实现onDraw方法,进行我们的绘制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //移动画布到圆环的左上角 canvas.translate(mWidth / 2 - mRadius / 2, mHeight / 2 - mRadius / 2); //初始化画笔 initPaint(); //画圆环 drawCycle(canvas); //画文字和标注 drawTextAndLabel(canvas); } /** * 初始化画笔 */ private void initPaint() { //边框画笔 cyclePaint = new Paint(); cyclePaint.setAntiAlias(true); cyclePaint.setStyle(Paint.Style.STROKE); cyclePaint.setStrokeWidth(mStrokeWidth); //文字画笔 textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setColor(textColor); textPaint.setStyle(Paint.Style.STROKE); textPaint.setStrokeWidth(1); textPaint.setTextSize(textSize); //标注画笔 labelPaint = new Paint(); labelPaint.setAntiAlias(true); labelPaint.setStyle(Paint.Style.FILL); labelPaint.setStrokeWidth(2); } /** * 画圆环 * * @param canvas */ private void drawCycle(Canvas canvas) { float startPercent = 0; float sweepPercent = 0; for (int i = 0; i < strPercent.length; i++) { cyclePaint.setColor(mColor[i]); startPercent = sweepPercent + startPercent; //这里采用比例占100的百分比乘于360的来计算出占用的角度,使用先乘再除可以算出值 sweepPercent = strPercent[i] * 360 / 100; canvas.drawArc(new RectF(0, 0, mRadius, mRadius), startPercent, sweepPercent, false, cyclePaint); } } /** * 画文字和标注 * * @param canvas */ private void drawTextAndLabel(Canvas canvas) { for (int i = 0; i < strPercent.length; i++) { //文字离右边环边距为60,文字与文字之间的距离为40 canvas.drawText(str[i], mRadius + 60, i * 40, textPaint); //画标注,标注离右边环边距为40,y轴则要减去半径(10)的一半才能对齐文字 labelPaint.setColor(mColor[i]); canvas.drawCircle(mRadius + 40, i * 40 - 5, 10, labelPaint); } }
步骤四:分析上面代码的绘制过程
思路分析:
1、画布移到圆环的左上角,为(0,0)。
2、画圆环:使用drawArc方法画出一个直径为mRadius的圆环,从初始角度开始,扫过多少角度。这里使用初始角度的递增方法使圆环一段接上一段的画出来。如果想让圆环旋转起来,就修改startPercent的值即可。
3、画文字和标注:将文字和标注画于圆环的右上角,也即圆的直径加上一段间距即可,同理,标注也是。
最后献上这个类的源码:源码下载
public class MyChatView extends View { //-------------必须给的数据相关------------- private String[] str = new String[]{"一年级", "二年级", "三年级", "四年级", "五年级", "六年级"}; //分配比例大小,总比例大小为100,由于经过运算后最后会是99.55左右的数值,导致圆不能够重合,会留出点空白,所以这里的总比例大小我们用101 private int[] strPercent = new int[]{10, 25, 18, 41, 2, 5}; //圆的直径 private float mRadius = 300; //圆的粗细 private float mStrokeWidth = 40; //文字大小 private int textSize = 20; //-------------画笔相关------------- //圆环的画笔 private Paint cyclePaint; //文字的画笔 private Paint textPaint; //标注的画笔 private Paint labelPaint; //-------------颜色相关------------- //边框颜色和标注颜色 private int[] mColor = new int[]{0xFFF06292, 0xFF9575CD, 0xFFE57373, 0xFF4FC3F7, 0xFFFFF176, 0xFF81C784}; //文字颜色 private int textColor = 0xFF000000; //-------------View相关------------- //View自身的宽和高 private int mHeight; private int mWidth; public MyChatView(Context context) { super(context); } public MyChatView(Context context, AttributeSet attrs) { super(context, attrs); } public MyChatView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //移动画布到圆环的左上角 canvas.translate(mWidth / 2 - mRadius / 2, mHeight / 2 - mRadius / 2); //初始化画笔 initPaint(); //画圆环 drawCycle(canvas); //画文字和标注 drawTextAndLabel(canvas); } /** * 初始化画笔 */ private void initPaint() { //边框画笔 cyclePaint = new Paint(); cyclePaint.setAntiAlias(true); cyclePaint.setStyle(Paint.Style.STROKE); cyclePaint.setStrokeWidth(mStrokeWidth); //文字画笔 textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setColor(textColor); textPaint.setStyle(Paint.Style.STROKE); textPaint.setStrokeWidth(1); textPaint.setTextSize(textSize); //标注画笔 labelPaint = new Paint(); labelPaint.setAntiAlias(true); labelPaint.setStyle(Paint.Style.FILL); labelPaint.setStrokeWidth(2); } /** * 画圆环 * * @param canvas */ private void drawCycle(Canvas canvas) { float startPercent = 0; float sweepPercent = 0; for (int i = 0; i < strPercent.length; i++) { cyclePaint.setColor(mColor[i]); startPercent = sweepPercent + startPercent; //这里采用比例占100的百分比乘于360的来计算出占用的角度,使用先乘再除可以算出值 sweepPercent = strPercent[i] * 360 / 100; canvas.drawArc(new RectF(0, 0, mRadius, mRadius), startPercent, sweepPercent, false, cyclePaint); } } /** * 画文字和标注 * * @param canvas */ private void drawTextAndLabel(Canvas canvas) { for (int i = 0; i < strPercent.length; i++) { //文字离右边环边距为60,文字与文字之间的距离为40 canvas.drawText(str[i], mRadius + 60, i * 40, textPaint); //画标注,标注离右边环边距为40,y轴则要减去半径(10)的一半才能对齐文字 labelPaint.setColor(mColor[i]); canvas.drawCircle(mRadius + 40, i * 40 - 5, 10, labelPaint); } } }