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上下載完整代碼

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