Android绘制饼状图

有兴趣可以查看上传的demo。下面做了简单的说明demo中的注解很详细,有问题欢迎交流

实现功能:

1.首次进入加载动画

2.数据过多可自动折行的图例(左侧)

3.饼状图折线指向的文案说明

4.手指滑动旋转

先上了效果图实现了如上四点功能如果对你有参考意义的,可以接着听我叨叨

先前项目引入的MPAndroidChart,但只是用了一两个图就把整个库引进来有点浪费。闲来无事决定自己写一个,先来说说思路:

1.先画一个饼状图

2.实现入场的旋转动画

    /**
     * 差值器生成数值
     */
    public void startAnima() {
        final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0f, 360f);
        mValueAnimator.setDuration(3 * 1000);

        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimaAngle = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator.start();
    }

 

3.实现折线指向的说明

以在第一象限举例:扇形角的平分线OP 分别在N、C、M点向x轴做垂线。因为canvas.drawArc是以x轴正方向为起点即0度开始顺时针画圆(所以下边表示的角度都是顺时针表示如 角LOT:是从x轴和OT线顺时针扫过区域所成的夹角

float a = 360 - (角LOT +角TOL / 2);

已知角a可以计算出N、M、P点的坐标。上边计算出来的都是相对于圆心O的坐标,还要转换成相对于View的坐标。

通过上边的操作可以画出折线和直线

     * •--------------------------------------> canvasX +
     * |
     * |                    P    Q         圆心为点 O,角用小些字母表示,点使用大写字母表示
     * |                     •- -• 北京     N:ON为内圆半径(innerRadius)
     * |        ^y          /              M:OM为外圆半径(outRadius)
     * |         |         /               P:P点为指向说明的拐点
     * |         |      M •                C:NM的中点
     * |         |       /|
     * |         |    C •角平分线
     * |         |     /| |
     * |         |  N • | |
     * |         |   /| | |   第一象限
     * |      T  |  / | | |
     * |       \ | /  | | |
      圆心(x,y) \|/╮ a|H|J|L
     * | --------•----•-•-•--------------------->x
     * |   | f╰ /|﹨╯ b |
     * |   |   / | ﹨   |   第二象限
     * |   |  /  |  ﹨  |   角b = sweepAngle/2 + startAngle;
     * |   | /   |   ﹨ |   因为角B的起始点不一定是0度
     * |   |/    |    ﹨|
     * |   •            • D 角平分线
     * |  第三象限
     * |
     * ∨ canvasY +

4.实现图例

实现图例主要有两个需要注意的点:

1.确定好扇形图的位置不能和图例相互遮挡

2.图例中的色块和右侧的文字需要居中对齐,这个需要计算出文本的baseline

drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

x,y并不是指定文字的左上角,并且x,y与文字对齐方式有关(通过setTextAlign()指定,默认为left)

红色的Baseline是基准线,紫色的Top是文字的最顶部,也就是在drawText()中指定的x所对应,橙色的Bottom是文字的底部。

baseline对应对应值为0,在它下面的descent和bottom值为正,top和ascent为负。那文字的高度为bottom - top

Paint.FontMetrics fontMetrics=paint.getFontMetrics();
        fontMetrics.top
        fontMetrics.ascent
        fontMetrics.descent
        fontMetrics.bottom
        //计算baseline
        Paint.FontMetrics fontMetrics=textPaint.getFontMetrics();
        float distance=(fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
        float baseline=显示文本区域y轴中心点的坐标 + distance;

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值