Android Canvas练习(2)自已绘饼图(Pie Chart)
上文弄了个绘制报表的,有了报表,当然想一并也绘个饼图,柱形图之类的玩玩,看看了API,觉得应当很简单,饼图实现了下,
实现代码确实也很简单,Android的这些函数封装的确实好用。
效果图如下:
不过实现过程还是比较曲折的,首先碰到一个sdk的bug,drawTextOnPath()用法明明是对的,但老是不显示没效果,后面
才查到,这个是BUG,后来在http://blog.csdn.net/yanzi1225627/article/details/8583066 上查到解决方法是在view的构造函数里设置this.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 才算能继续下去。
package com.xcl.chart;/** * Canvas练习 * 自已画饼图,实现出来后觉得也算实用. * * author:xiongchuanliang * date:2014-4-6 */import android.annotation.SuppressLint;import android.content.Context;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Path.Direction;import android.graphics.RectF;import android.graphics.Typeface;import android.util.DisplayMetrics;import android.view.View;@SuppressLint("NewApi")public class PanelPieChart1 extends View {private int ScrHeight;private int ScrWidth;private Paint[] arrPaintArc;private Paint PaintText = null;/*final int[] colors = new int[]{R.color.red,R.color.white,R.color.green,R.color.yellow,R.color.blue,};*///RGB颜色数组private final int arrColorRgb[][] = { {77, 83, 97}, {148, 159, 181}, {253, 180, 90}, {52, 194, 188}, {39, 51, 72}, {255, 135, 195}, {215, 124, 124}, {180, 205, 230}} ;//演示用的比例,实际使用中,即为外部传入的比例参数final float arrPer[] = new float[]{20f,30f,10f,40f};public PanelPieChart1(Context context){super(context);//解决4.1版本 以下canvas.drawTextOnPath()不显示问题this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);//屏幕信息DisplayMetrics dm = getResources().getDisplayMetrics();ScrHeight = dm.heightPixels;ScrWidth = dm.widthPixels;//设置边缘特殊效果 BlurMaskFilter PaintBGBlur = new BlurMaskFilter( 1, BlurMaskFilter.Blur.INNER);arrPaintArc = new Paint[5];//Resources res = this.getResources();for(int i=0;i<5;i++){arrPaintArc[i] = new Paint();//arrPaintArc[i].setColor(res.getColor(colors[i] )); arrPaintArc[i].setARGB(255, arrColorRgb[i][0], arrColorRgb[i][1], arrColorRgb[i][2]);arrPaintArc[i].setStyle(Paint.Style.FILL);arrPaintArc[i].setStrokeWidth(4);arrPaintArc[i].setMaskFilter(PaintBGBlur);}PaintText = new Paint();PaintText.setColor(Color.BLUE);PaintText.setTextSize(22);//PaintText.setTypeface(Typeface.DEFAULT_BOLD);}public void onDraw(Canvas canvas){//画布背景canvas.drawColor(Color.WHITE);float cirX = ScrWidth / 2;float cirY = ScrHeight / 3 ;float radius = ScrHeight / 5 ;//150;//先画个圆确定下显示位置//canvas.drawCircle(cirX,cirY,radius,PaintArcRed);float arcLeft = cirX - radius;float arcTop = cirY - radius ;float arcRight = cirX + radius ;float arcBottom = cirY + radius ;RectF arcRF0 = new RectF(arcLeft ,arcTop,arcRight,arcBottom);Path pathArc=new Path(); // x,y,半径 ,CWpathArc.addCircle(cirX,cirY,radius,Direction.CW); //绘出饼图大轮廓canvas.drawPath(pathArc,arrPaintArc[0]); float CurrPer = 0f; //偏移角度float Percentage = 0f; //当前所占比例int scrOffsetW = ScrWidth - 200;int scrOffsetH = ScrHeight - 300;int scrOffsetT = 40;//Resources res = this.getResources();int i= 0;for(i=0; i<3; i++) //注意循环次数噢{//将百分比转换为饼图显示角度Percentage = 360 * (arrPer[i]/ 100);Percentage = (float)(Math.round(Percentage *100))/100; //在饼图中显示所占比例canvas.drawArc(arcRF0, CurrPer, Percentage, true, arrPaintArc[i+2]); //当前颜色canvas.drawRect(scrOffsetW ,scrOffsetH + i * scrOffsetT,scrOffsetW + 60 ,scrOffsetH - 30 + i * scrOffsetT, arrPaintArc[i+2]);//当前比例canvas.drawText(String.valueOf(arrPer[i]) +"%",scrOffsetW + 70,scrOffsetH + i * scrOffsetT, PaintText);//下次的起始角度CurrPer += Percentage;}//最末尾比例说明canvas.drawRect(scrOffsetW ,scrOffsetH + i * scrOffsetT,scrOffsetW + 60 ,scrOffsetH - 30 + i * scrOffsetT, arrPaintArc[0]);canvas.drawText(String.valueOf(arrPer[i]) +"%",scrOffsetW + 70,scrOffsetH + i * scrOffsetT, PaintText);//Demo的作者信息canvas.drawText("author:xcl",70,scrOffsetH + i+1 * scrOffsetT, PaintText);canvas.drawText("date:2014-4-7",70,scrOffsetH + i * scrOffsetT, PaintText);}}
代码注释算比较详细,就不多说了,主要整理下我实现过程中了解到的一些使用方法.
RectF 定义矩形,这个用得很多,定坐标时,脑子中一定要有一个清楚的印象,示意图如下:
要是在实现时确定不了,可以用canvas.drawRect(new RectF(left, top, right bottm), paint); 在屏幕上画出来看看效果。
Path: 官网Doc
这个在可以先用下面的代码看看效果:
Paint paint = new Paint();paint.setColor(Color.GREEN);paint.setStyle(Paint.Style.STROKE);Path p = new Path();p.moveTo(20,20);p.lineTo(100,200);p.lineTo(200,100);p.lineTo(240,155);canvas.drawPath(p,paint);效果如下:
path不断可以画线,还可以有特殊的用法:
其实现代码如下:
float cirX = ScrWidth / 2;float cirY = ScrHeight / 3 ;float radius = ScrHeight / 5 ; Path pathArc=new Path(); // x,y,半径 ,CW为顺时针绘制pathArc.addCircle(cirX,cirY,radius,Direction.CW); canvas.drawPath(pathArc,arrPaintArc[0]); canvas.drawTextOnPath("环绕文字",pathArc,0,30,PaintText); //在路径上绘制文字对path,如果不确实效果,可以用drawPath打印出来看看,如果打印出来是一片空白,则有可能是你输入的位置参数不正确所致
drawTextOnPath 函数原型:
drawTextOnPath (String text,Path ath,float hOffset,float vOffset,Pating paint)
这个函数能让文字跟着path跑,hOffset参数指定水平偏移 vOffset参数指定垂直偏移量是多少。
drawArc()函数画圆弧的,一个最典型的用法如下:
canvas.drawArc(new RectF(0, 0, 128, 128), 0,120, true, new Paint( Paint.ANTI_ALIAS_FLAG));饼图百分比的扇形图主要就是用它来实现的。
还有一个Style属性要说下,它决定了是空心,还是实心之类。
Paint.Style.STROKE:Only draw the outline of the shapes
Paint.Style.FILLE:Only fill the shapes
Paint.Style.FILL_AND_STROKE:Fill and draw the outline of the shapes
大致就这些了。
附其它绘制图表的链接:
Android Canvas练习(1)画一张报表来玩
Android Canvas练习(2)自已绘饼图
Android Canvas练习(3)自已绘柱形图
Android Canvas练习(4)自已绘折线图
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168
更多相关文章
- (源码)200多种Android动画效果的强悍框架、外卖020的演示客户端、a
- Android中你也许不知道的线性布局Layout_weight属性权重比例分配
- Android之gallery 常见2种使用方法和3D效果总结
- Android Tween动画之RotateAnimation实现图片不停旋转效果实例介
- Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果
- 通过Canvas的叠加实现Android中环形View的颜色填充动画效果
- Android实训案例(三)——实现时间轴效果的ListView,加入本地存储
- Android实现LED灯显示效果