Android自定义控件之动态柱状图

这里写图片描述

设计思路:

1.画柱状图
2.画竖线
3.画顶部横线
4.画文字

1.画柱状图

画柱状图的方法很简单,就是使用canvas.drawRect(float left, float top, float right, float bottom, Paint paint),其实这里我遇到了一个问题,一开始我想只画一条柱状图,然后需要几个柱状图就在xml文件中声明几个,后来我发现,这样实现起来的动画非常之卡顿(上面gif录出来看上去很卡,其实很流畅)。后来我就换了一种思路,就是声明一个数组,在Activity传入我们需要画的柱状图的总个数和每个柱状图的目标值大小,然后在onDraw方法里分别计算每个柱状图的当前进度,然后分别画出来,这样动画效果就非常流畅了。

 /**
         * 画柱状图
         */
        for(int i = 0 ; i<totalBarNum ; i++){
            if (currentBarProgress[i]<(respTarget.get(i)/max)*stopX) {
                currentBarProgress[i]+=10;
                postInvalidateDelayed(10);
            }
            canvas.drawText(respName.get(i),startX,startY+deltaY+i*(deltaY+barWidth)+3*barWidth/4, mTextPaint);
            canvas.drawRect(startX+7*barWidth/5, startY+deltaY+i*(deltaY+barWidth), currentBarProgress[i], startY+deltaY+i*(deltaY+barWidth)+barWidth, mBarPaint);
        }

2.画竖线和文字

有了上面画柱状图的思路,画竖线就非常容易想了,和画柱状图是一个思路,也是Activity中传入需要画几条竖线,然后在onDraw方法里分别去计算他们的当前进度值,然后再分别去画

文字大小应该随着柱形图宽度来自动适应,所以我进行了一些计算,看上去很复杂,其实就是为了自适应文字的大小

 /**
         * 画竖线
         */
        for(int i=0 ; i<verticalLineNum ; i++){
            if (currentVerticalLineProgress< measuredHeight) {
                currentVerticalLineProgress+=3;
                postInvalidateDelayed(10);
            }
            canvas.drawLine((startX+7*barWidth/5)+(i+1)*deltaX, startY, (startX+7*barWidth/5)+(i+1)*deltaX, currentVerticalLineProgress, mLinePaint);
            //画文字
            canvas.drawText(numPerUnit*(i+1)+unit, (startX+7*barWidth/5)+(i+1)*deltaX-barWidth, startY-barWidth/5, mTextPaint);
        }

3.画顶部横线

顶部横线我是从右向左画的,正好与柱状图形成一个对比

 /**
         * 画最上面的横线
         */
        if (currentHorizentalLineProgress>startX+7*barWidth/5) {
            currentHorizentalLineProgress-=10;
            postInvalidateDelayed(10);
        }
        canvas.drawLine(stopX, startY, currentHorizentalLineProgress, startY, mLinePaint);
    }

使用方法

1.设置柱状图的最大值

mBarGraph.setMax(40);

2.设置柱状图单位

mBarGraph.setUnit("亿元");

3.设置柱状图宽度

mBarGraph.setBarWidth(50);

4.设置竖线条数

mBarGraph.setVerticalLineNum(4);

5.设置柱状图总个数

 mBarGraph.setTotalBarNum(7);

6.设置每个柱状图的目标值

 private ArrayList<Float> respectTarget;
 ...
 respectTarget = new ArrayList<Float>();
 respectTarget.add(35.0f);
        respectTarget.add(20.0f);
        respectTarget.add(18.0f);
        respectTarget.add(15.0f);
        respectTarget.add(10.0f);
        respectTarget.add(8.0f);
        respectTarget.add(5.0f);
  mBarGraph.setRespectTargetNum(respectTarget);

7.设置每个柱状图的名字

private ArrayList<String> respName;
...
respName = new ArrayList<String>();
 respName.add("滴滴");
        respName.add("小米");
        respName.add("京东");
        respName.add("美团");
        respName.add("魅族");
        respName.add("酷派");
        respName.add("携程");
mBarGraph.setRespectName(respName);

完整代码

大家可以上我的GitHub上下载完整代码

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章