全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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;
  /**
   * 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程序设计有所帮助。


# Android  # canvas  # 绘制  # 饼状  # 统计图  # Android中使用Canvas绘制南丁格尔玫瑰图(Nightingale rose diagram  # Android编程之canvas绘制各种图形(点  # 直线  #   #   # 椭圆  # 文字  # 矩形  # 多边形  # 曲线  # 圆角矩形)  # Android编程开发之在Canvas中利用Path绘制基本图形(圆形  # 三角形等)  # Android使用Canvas绘制圆形进度条效果  # Android编程实现canvas绘制柱状统计图功能【自动计算宽高及分度值、可左右滑动】  # Android开发使用自定义View将圆角矩形绘制在Canvas上的方法  # Android 使用Canvas在图片上绘制文字的方法  # Android Canvas绘制文字横纵向对齐  # 自适应  # 进阶  # 放在  # 相关内容  # 下划线  # 感兴趣  # 给大家  # 点击此处  # 更多关于  # 解决方法  # 所述  # 图像处理  # 程序设计  # 往右  # 往左  # 本例  # 讲述了  # 目的是  # float 


相关文章: 如何在建站宝盒中设置产品搜索功能?  c++怎么用jemalloc c++替换默认内存分配器【性能】  如何快速搭建二级域名独立网站?  微信h5制作网站有哪些,免费微信H5页面制作工具?  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  导航网站建站方案与优化指南:一站式高效搭建技巧解析  建站主机选哪家性价比最高?  香港网站服务器数量如何影响SEO优化效果?  Android自定义控件实现温度旋转按钮效果  如何挑选最适合建站的高性能VPS主机?  宝塔新建站点为何无法访问?如何排查?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  建站主机是否属于云主机类型?  完全自定义免费建站平台:主题模板在线生成一站式服务  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?  如何做网站制作流程,*游戏网站怎么搭建?  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  如何快速搭建FTP站点实现文件共享?  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  教程网站设计制作软件,怎么创建自己的一个网站?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  如何在阿里云香港服务器快速搭建网站?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  自助网站制作软件,个人如何自助建网站?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  大同网页,大同瑞慈医院官网?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  网站制作公司排行榜,抖音怎样做个人官方网站  网站app免费制作软件,能免费看各大网站视频的手机app?  网站企业制作流程,用什么语言做企业网站比较好?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  家庭服务器如何搭建个人网站?  建站之星免费模板:自助建站系统与智能响应式一键生成  如何快速上传自定义模板至建站之星?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何用PHP工具快速搭建高效网站?  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  制作营销网站公司,淘特是干什么用的?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  如何在宝塔面板创建新站点?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  建站三合一如何选?哪家性价比更高?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。