1.画柱状图
2.画竖线
3.画顶部横线
4.画文字
画柱状图的方法很简单,就是使用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);
}
有了上面画柱状图的思路,画竖线就非常容易想了,和画柱状图是一个思路,也是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);
}
顶部横线我是从右向左画的,正好与柱状图形成一个对比
/** * 画最上面的横线 */
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上下载完整代码