自定義餅狀圖View(一)

最近公司做項目的時候遇到一個需求雨效,市場分布要用餅狀圖來顯示迅涮。網(wǎng)上找了幾個感覺都不是很符合需求。正當愁眉苦臉的時候徽龟,產品突然說不需要這個需求了叮姑。然后就這么放下來了。現(xiàn)在就自己琢磨著是不是嘗試自己寫一個出來据悔。會在這里慢慢更新传透,如果有什么問題可以直接提出來。樓主小白一枚屠尊。在慢慢摸索旷祸!

首先需要說一下的是本文適合新手小白來看,基礎較好的人可能會覺得太過于簡單讼昆。

先上一個最終需要實現(xiàn)的效果托享。

最終效果.jpg
最終效果2.jpg

但是目前的顯示效果是:

初始顯示效果

這個是餅狀圖最簡單的顯示方式,上面沒有任何表示浸赫。只是一個單純的顏色顯示闰围。
理想和現(xiàn)實的差距是不是特別明顯。但是還是要上一下代碼既峡,畢竟沒代碼嗶嗶啥羡榴!

public class PieChartView extends View {

    // 默認的顏色
    private int[] mColors = {0xFF00FF00, 0xFFFF0000, 0xFF0000FF, 0xFF0F0F0F, 0xFFF0F0F0, 0xFFFF0F0F, 0xFFFFFFFF,
            0xFFEEEEEE, 0xFFBBBBBB};
    // 餅狀圖從哪里開始繪制
    private float mStartAngle = 0;
    // 需要的數(shù)據(jù)
    private ArrayList<PieData> mData;
    // 寬高
    private int mWidth, mHeight;
    // 畫筆
    private Paint mPaint = new Paint();
    private float value;

    public PieChartView(Context context) {
        this(context, null);
    }

    public PieChartView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PieChartView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //設置繪畫模式
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        //設置抗鋸齒
        mPaint.setAntiAlias(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mData == null) {
            return;
        }
        float currentStartAngle = mStartAngle;                    // 當前起始角度
        canvas.translate(mWidth / 2, mHeight / 2);                // 將畫布坐標原點移動到中心位置
        float r = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);  // 餅狀圖半徑
        RectF rect = new RectF(-r, -r, r, r);                     // 餅狀圖繪制區(qū)域

        for (int i = 0; i < mData.size(); i++) {
            PieData pie = mData.get(i);
            mPaint.setColor(pie.getColor());
            canvas.drawArc(rect, currentStartAngle, pie.getAngle(), true, mPaint);
            currentStartAngle += pie.getAngle();
        }

    }

    /**
     * 設置數(shù)據(jù)的方法
     *
     * @param data
     */
    public void setmData(ArrayList<PieData> data) {
        this.mData = data;
        initData(mData);
        invalidate();
    }

    /**
     * 設置顏色的方法
     *
     * @param mColors
     */
    public void setmColors(int[] mColors) {
        this.mColors = mColors;
        invalidate();
    }


    /**
     * 設置從哪兒開始繪畫
     *
     * @param startAngle
     */
    public void setmStartAngle(int startAngle) {
        this.mStartAngle = startAngle;
        invalidate();
    }

    /**
     * 初始化數(shù)據(jù)的方法
     *
     * @param data
     */
    private void initData(ArrayList<PieData> data) {
        if (data == null || data.size() == 0) {
            return;
        }
        float sumValue = 0;
        for (int i = 0; i < data.size(); i++) {
            PieData pieData = data.get(i);
            sumValue += pieData.getValue();
            int color = i % mColors.length;
            pieData.setColor(mColors[color]);
        }

        float sumAngle = 0;
        for (int i = 0; i < data.size(); i++) {
            PieData pieData = data.get(i);
            float percentage = pieData.getValue() / sumValue;
            pieData.setPercentage(percentage);
            pieData.setAngle(percentage * 360);
            sumAngle += percentage * 360;
        }

    }

}
繪畫開始角度.png

可以看出來.當開始角度是0的時候,系統(tǒng)是從三點鐘方向開始順時針繪畫.

PieData 需要的數(shù)據(jù)
這個只是模擬的數(shù)據(jù),以及以后需要在餅狀圖上顯示的數(shù)據(jù).

    private String name; //數(shù)據(jù)的名稱
    private float value; //數(shù)據(jù)的值

/*------------------我是華麗的分割線------------------*/
  
    private float percentage; //每個數(shù)據(jù)占總數(shù)的百分比
    private int color = 0;      // 數(shù)據(jù)在餅狀圖的顏色
    private float angle = 0;    //數(shù)據(jù)在圖中所占的角度

    public PieData(String name, float value) {
        this.name = name;
        this.value = value;
    }

MainActivity

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pieChartView = (PieChartView) findViewById(R.id.pie_chart);
        pieChartView.setmStartAngle(180);
        int[] colors = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF};
        pieChartView.setmColors(colors);
        for (int i = 0; i < 5; i++) {
            switch (i) {
                case 0:
                    mDatas.add(new PieData("語文",100));
                    break;
                case 1:
                    mDatas.add(new PieData("數(shù)學",200));
                    break;
                case 2:
                    mDatas.add(new PieData("英語",150));
                    break;
                case 3:
                    mDatas.add(new PieData("物理",100));
                    break;
                case 4:
                    mDatas.add(new PieData("化學",120));
                    break;
            }
        }
        pieChartView.setmData(mDatas);
    }

比較值得注意的幾個點就是繪畫的時候要注意到百分比的計算和顏色的分配。這個view比較簡單运敢,相信代碼貼上來基本都能看懂校仑。沒什么需要單獨去解釋的忠售,如果有什么問題,請大家留言或者私信迄沫。本文會持續(xù)更新稻扬。直到達到最終效果。么么噠羊瘩!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末泰佳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尘吗,更是在濱河造成了極大的恐慌逝她,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睬捶,死亡現(xiàn)場離奇詭異黔宛,居然都是意外死亡,警方通過查閱死者的電腦和手機侧戴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門宁昭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酗宋,你說我怎么就攤上這事积仗。” “怎么了蜕猫?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵寂曹,是天一觀的道長。 經(jīng)常有香客問我回右,道長隆圆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任翔烁,我火速辦了婚禮渺氧,結果婚禮上,老公的妹妹穿的比我還像新娘蹬屹。我一直安慰自己侣背,他們只是感情好,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布慨默。 她就那樣靜靜地躺著贩耐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厦取。 梳的紋絲不亂的頭發(fā)上潮太,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天,我揣著相機與錄音,去河邊找鬼铡买。 笑死更鲁,一個胖子當著我的面吹牛,可吹牛的內容都是我干的奇钞。 我是一名探鬼主播岁经,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛇券!你這毒婦竟也來了?” 一聲冷哼從身側響起樊拓,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤纠亚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筋夏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒂胞,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年条篷,在試婚紗的時候發(fā)現(xiàn)自己被綠了骗随。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡赴叹,死狀恐怖鸿染,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情乞巧,我是刑警寧澤涨椒,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站绽媒,受9級特大地震影響蚕冬,放射性物質發(fā)生泄漏。R本人自食惡果不足惜是辕,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一囤热、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧获三,春花似錦旁蔼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至松逊,卻和暖如春躺屁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背经宏。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工犀暑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驯击,地道東北人。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓耐亏,卻偏偏與公主長得像徊都,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子广辰,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內容