1. 程式人生 > >自定義餅狀圖控制元件PieView

自定義餅狀圖控制元件PieView

本篇參考:GcsSloop的安卓自定義View進階-Canvas之繪製圖形


這裡寫圖片描述

一、分析如上餅狀圖,所需要得資訊如下

  1. 各塊的顏色
  2. 所有塊量得總和
  3. 各個塊得量佔總量的百分比,並通過百分比得到各個塊所佔扇形的弧度
  4. 第一個塊得起始角度
  5. 該 View 控制元件的寬高及位置

二、具體控制元件邏輯

  1. javabean

    public class PieData {
        // 使用者操作資料
        private String name;        // 名字
        private float value
    ; // 數值 private float percentage; // 百分比 // 非使用者操作資料 private int color = 0; // 顏色 private float angle = 0; // 角度 public PieData(String name, float value) { this.name = name; this.value = value; } ... // set/get省略 }
  2. 自定義PieView

    public class PieView extends
    View {
    // 1. 各塊的顏色 private int[] mColors = {0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080, 0xFFE6B800, 0xFF7CFC00}; // 2. 第一塊的初始角度 private float mStartAngle = 180; // 資料集合 private ArrayList<PieData> mDatas; // 控制元件寬高 private int mWidth, mHeight; // 畫筆 private
    Paint mPaint = new Paint(); public PieView(Context context) { this(context, null); } public PieView(Context context, AttributeSet attrs) { super(context, attrs); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); } // 記錄當前View控制元件的寬高 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; } // 設定起始角度並重新整理介面 public void setStartAngle(int mStartAngle) { this.mStartAngle = mStartAngle; invalidate(); } // 設定資料並重新整理介面 public void setData(ArrayList<PieData> mData) { this.mDatas = mData; initData(mData); invalidate(); } // 餅狀圖中資料的處理 float sumValue = 0; // 所有塊的資料總量 float piePercentage = 0; // 各塊佔資料總量的百分比 float sumAngle = 0; // 所有塊佔的總扇形角度 float pieAngle = 0; // 各塊佔的扇形角度 private void initData(ArrayList<PieData> mDatas) { // 判空 if (null == mDatas || mDatas.size() == 0) { return; } for (int i = 0; i < mDatas.size(); i++) { PieData pie = mDatas.get(i); // 1. 設定各塊顏色 int j = i % mColors.length; pie.setColor(mColors[j]); // 2. 統計所有塊的資料總量 sumValue += pie.getValue(); // 3. 計算各塊量佔總量的百分比 piePercentage = pie.getValue() / sumValue; // 4. 通過各塊量的佔比計算所佔扇形角度 pieAngle = piePercentage * 360; pie.setPercentage(piePercentage); pie.setAngle(pieAngle); sumAngle += pieAngle; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 判空 if (null == mDatas || mDatas.size() == 0) { 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); for (int i = 0; i < mDatas.size(); i++) { PieData pie = mDatas.get(i); mPaint.setColor(pie.getColor()); canvas.drawArc(rect, currentStartAngle, pie.getAngle(), true, mPaint); currentStartAngle += pie.getAngle(); } } }
  3. 針對上述部分程式碼片的圖解

    這裡寫圖片描述