Android 扇形统计图的设计与编写

论坛 期权论坛     
选择匿名的用户   2021-6-2 15:38   184   0
<p>先上图,包含统计图初始化时的动画,点击环形的效果</p>
<p><img alt="没有数据时状态" class="blockcode" height="339" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-56aaf7e58afe81f4047968800036f75a.jpg" width="288"><img alt="" class="blockcode" height="347" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-57eed2564510d6579360e2860439879e.jpg" width="302"><img alt="" class="blockcode" height="346" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-fc18ef5e0845e0347aa67edd1869799a.jpg" width="292"></p>
<p>饼状图根据效果不同,调用的APi参数略微有差异,有些同学可能不想要中间的空白直接全部展示扇形,emmmm。这种需求比你现在看到的这个样子 要简单的多,看完这种样式的,其他的实现方式也就懂了。</p>
<p>首先,实现思路不能落下:</p>
<p>1、在自定义View里面初始化的时候(构造方法里),</p>
<pre class="blockcode"><code>setLayerType(View.LAYER_TYPE_SOFTWARE, null);</code></pre>
<p><strong>这行代码不能忘,这个是硬件加速,某些低端手机上如果不写着一行,阴影部分无法展示,而且相邻扇形图无法无缝对接,即便看起来你的代码并没有什么问题。</strong></p>
<p>2、计算画布的大小以及定位我们的<strong>统计图位置</strong></p>
<pre class="blockcode"><code>&#64;Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
//View宽高
        mTotalWidth &#61; w - getPaddingLeft() - getPaddingRight();
        mTotalHeight &#61; h - getPaddingTop() - getPaddingBottom();
        //饼状图半径
        mRadius &#61; WindowsUtil.dp2px(178) / 2;
        //参与计算的扇形半径(我们是画一个空心圆,例如:画圆的线的粗为2,实际需要半径为10,如果输入参数时半径不减去线粗的1/2的话 看到的环形外圈半径为11,内圈半径为9)
        calculateRadius &#61; mRadius - mRadius / 4;
        mRectF.left &#61; -calculateRadius;
        mRectF.top &#61; -calculateRadius;
        mRectF.right &#61; calculateRadius;
        mRectF.bottom &#61; calculateRadius;
    }

    &#64;Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
           //限定位置(原点为中心点)
        canvas.translate(mTotalWidth / 2, mTotalHeight / 2);
        //绘制饼图的每块区域
        drawPiePath(canvas);

    }</code></pre>
<p>3、好了,直接说重点,看看 <strong>drawPiePath(canvas)</strong>;方法里怎么操作,怎么去绘制的</p>
<pre class="blockcode"><code> /**
     * 绘制饼图的每块区域 和文本
     *
     * &#64;param canvas
     */
    private void drawPiePath(Canvas canvas) {
        //起始地角度
        float startAngle &#61; starAngle;
        if (mDataList !&#61; null &amp;&amp; mDataList.size() &gt; 0) {

            for (int i &#61; 0; i &lt; mDataList.size(); i&#43;&#43;) {
                String name &#61; mDataList.get(i).getName() &#43; (int) mDataList.get(i).getValue();
                float sweepAngle &#61; mDataList.get(i).getValue() / mTotalValue * 360;//每个扇形的角度
                sweepAngle &#61; sweepAngle * percent;
                mPaint.setColor(mDataList.get(i).getColor());

                mLinePaint.setColor(mDataList.get(i).getColor());
                mTextPaint.setColor(mDataList.get(i).getColor());

                double x1, y1;
                int addLength &#61; 0;
                if (i !&#61; 0) {
                    if (i &gt; 3) {
                        for (int c &#61; 0; c &lt; maxListNumH; c&#43;&#43;) {
                            if (lineAndTextHorizontalAddress[i - c] &gt; 0) {
                                addLength &#43;&#61; WindowsUtil.dp2px(mTextPaint.measureText(name) / (maxListNumH * 2));
                            }
                        }
                    }
                    if (mDataList.get(i).getQuadrant() &#61;&#61; 1 || mDataList.get(i).getQuadrant() &#61;&#61; 3) {
                        x1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint.measureText(name) * 0.3);
                        y1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint.measureText(name) * 0.4);
                    } else {
                        if (mDataList.get(i - 1).getQuadrant() !&#61; mDataList.get(i).getQuadrant()) {
                            x1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint.measureText(name) * 0.3);
                            y1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint.measureText(name) * 0.4);
                        } else {
                            if (lineAndTextHorizontalAddress[i - 1] &#61;&#61; 0) {
                                x1 &#61; mRadius &#43; LineLength &#43; addLength;
                                y1 &#61; mRadius &#43; LineLength;
                            } else {
                                x1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint.measureText(name) * 0.3);
                                y1 &#61; mRadius &#43; LineLength &#43; lineAndTextHorizontalAddress[i] * (mTextPaint
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP