栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android编程实现canvas绘制饼状统计图功能示例

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android编程实现canvas绘制饼状统计图功能示例

本文实例讲述了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;
  
  private Paint textPaint, piePaint, linePaint;
  
  private int pieCenterX, pieCenterY, pieRadius;
  
  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程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/159977.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号