Android编程实现canvas绘制饼状统计图功能示例【自动适应条目数量与大小】
程序员文章站
2024-02-14 16:35:40
本文实例讲述了android编程实现canvas绘制饼状统计图功能。分享给大家供大家参考,具体如下:
本例的目的是实现一个简单的饼状统计图,效果如下:
&n...
本文实例讲述了android编程实现canvas绘制饼状统计图功能。分享给大家供大家参考,具体如下:
本例的目的是实现一个简单的饼状统计图,效果如下:
特点:
1.使用非常方便,可放在xml布局文件中,然后在代码中设置内容,即:
piechartview piechartview = (piechartview) findviewbyid(r.id.pie_chart); piechartview.pieitembean[] items = new piechartview.pieitembean[]{ new piechartview.pieitembean("娱乐", 200), new piechartview.pieitembean("旅行", 100), new piechartview.pieitembean("学习", 120), new piechartview.pieitembean("人际关系", 160), new piechartview.pieitembean("交通", 100), new piechartview.pieitembean("餐饮", 480) }; piechartview.setpieitems(items);
2.条目数量,大小及折线位置,长度均自适应。左侧条目往左侧划线,右侧条目往右侧划线,文字描述与百分比居中对齐,并且文字“下划线”与文字长度自适应。对于很小的条目,将自动将折线延长以尽可能避免文字遮盖
核心代码:piechartview.java:
public class piechartview extends view { private int screenw, screenh; /** * the paint to draw text, pie and line. */ private paint textpaint, piepaint, linepaint; /** * the center and the radius of the pie. */ private int piecenterx, piecentery, pieradius; /** * the oval to draw the oval in. */ private rectf pieoval; private float smallmargin; private int[] mpiecolors = new int[]{color.red, color.green, color.blue, color.yellow, color.magenta, color.cyan}; private pieitembean[] mpieitems; private float totalvalue; public piechartview(context context) { super(context); init(context); } public piechartview(context context, attributeset attrs) { super(context, attrs); init(context); } public piechartview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(context); } private void init(context context) { //init screen screenw = screenutils.getscreenw(context); screenh = screenutils.getscreenh(context); piecenterx = screenw / 2; piecentery = screenh / 3; pieradius = screenw / 4; smallmargin = screenutils.dp2px(context, 5); pieoval = new rectf(); pieoval.left = piecenterx - pieradius; pieoval.top = piecentery - pieradius; pieoval.right = piecenterx + pieradius; pieoval.bottom = piecentery + pieradius; //the paint to draw text. textpaint = new paint(); textpaint.setantialias(true); textpaint.settextsize(screenutils.dp2px(context, 16)); //the paint to draw circle. piepaint = new paint(); piepaint.setantialias(true); piepaint.setstyle(paint.style.fill); //the paint to draw line to show the concrete text linepaint = new paint(); linepaint.setantialias(true); linepaint.setstrokewidth(screenutils.dp2px(context, 1)); } //the degree position of the last item arc's center. private float lastdegree = 0; //the count of the continues 'small' item. private int addtimes = 0; @override protected void ondraw(canvas canvas) { super.ondraw(canvas); if (mpieitems != null && mpieitems.length > 0) { float start = 0.0f; for (int i = 0; i < mpieitems.length; i++) { //draw pie piepaint.setcolor(mpiecolors[i % mpiecolors.length]); float sweep = mpieitems[i].getitemvalue() / totalvalue * 360; canvas.drawarc(pieoval, start, sweep, true, piepaint); //draw line away from the pie float radians = (float) ((start + sweep / 2) / 180 * math.pi); float linestartx = piecenterx + pieradius * 0.7f * (float) (math.cos(radians)); float linestarty = piecentery + pieradius * 0.7f * (float) (math.sin(radians)); float linestopx, linestopy; float rate; if (getoffset(start + sweep / 2) > 60) { rate = 1.3f; } else if (getoffset(start + sweep / 2) > 30) { rate = 1.2f; } else { rate = 1.1f; } //if the item is very small, make the text further away from the pie to avoid being hided by other text. if (start + sweep / 2 - lastdegree < 30) { addtimes++; rate += 0.2f * addtimes; } else { addtimes = 0; } linestopx = piecenterx + pieradius * rate * (float) (math.cos(radians)); linestopy = piecentery + pieradius * rate * (float) (math.sin(radians)); canvas.drawline(linestartx, linestarty, linestopx, linestopy, linepaint); //write text string itemtypetext = mpieitems[i].getitemtype(); string itempercenttext = utility.formatfloat(mpieitems[i].getitemvalue() / totalvalue * 100) + "%"; float itemtypetextlen = textpaint.measuretext(itemtypetext); float itempercenttextlen = textpaint.measuretext(itempercenttext); float linetextwidth = math.max(itemtypetextlen, itempercenttextlen); float textstartx = linestopx; float textstarty = linestopy - smallmargin; float percentstartx = linestopx; float percentstarty = linestopy + textpaint.gettextsize(); if (linestartx > piecenterx) { textstartx += (smallmargin + math.abs(itemtypetextlen - linetextwidth) / 2); percentstartx += (smallmargin + math.abs(itempercenttextlen - linetextwidth) / 2); } else { textstartx -= (smallmargin + linetextwidth - math.abs(itemtypetextlen - linetextwidth) / 2); percentstartx -= (smallmargin + linetextwidth - math.abs(itempercenttextlen - linetextwidth) / 2); } canvas.drawtext(itemtypetext, textstartx, textstarty, textpaint); //draw percent text canvas.drawtext(itempercenttext, percentstartx, percentstarty, textpaint); //draw text underline float textlinestopx = linestopx; if (linestartx > piecenterx) { textlinestopx += (linetextwidth + smallmargin * 2); } else { textlinestopx -= (linetextwidth + smallmargin * 2); } canvas.drawline(linestopx, linestopy, textlinestopx, linestopy, linepaint); lastdegree = start + sweep / 2; start += sweep; } } } public pieitembean[] getpieitems() { return mpieitems; } public void setpieitems(pieitembean[] pieitems) { this.mpieitems = pieitems; totalvalue = 0; for (pieitembean item : mpieitems) { totalvalue += item.getitemvalue(); } invalidate(); } private float getoffset(float radius) { int a = (int) (radius % 360 / 90); switch (a) { case 0: return radius; case 1: return 180 - radius; case 2: return radius - 180; case 3: return 360 - radius; } return radius; } static class pieitembean { private string itemtype; private float itemvalue; pieitembean(string itemtype, float itemvalue) { this.itemtype = itemtype; this.itemvalue = itemvalue; } public string getitemtype() { return itemtype; } public void setitemtype(string itemtype) { this.itemtype = itemtype; } public float getitemvalue() { return itemvalue; } public void setitemvalue(float itemvalue) { this.itemvalue = itemvalue; } } }
完整实例代码点击此处本站下载。
更多关于android相关内容感兴趣的读者可查看本站专题:《android图形与图像处理技巧总结》、《android开发入门与进阶教程》、《android调试技巧与常见问题解决方法汇总》、《android基本组件用法总结》、《android视图view技巧总结》、《android布局layout技巧总结》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。
上一篇: iOS 进度条、加载、安装动画的简单实现
下一篇: Android编程之通知栏的用法小结