欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android編程實現(xiàn)canvas繪制餅狀統(tǒng)計圖功能示例【自動適應(yīng)條目數(shù)量與大小】

 更新時間:2017年01月25日 12:05:08   作者:books1958  
這篇文章主要介紹了Android編程實現(xiàn)canvas繪制餅狀統(tǒng)計圖功能,可實現(xiàn)自動適應(yīng)條目數(shù)量與大小的功能,涉及Android基于canvas的圖形繪制相關(guān)操作技巧,需要的朋友可以參考下

本文實例講述了Android編程實現(xiàn)canvas繪制餅狀統(tǒng)計圖功能。分享給大家供大家參考,具體如下:

本例的目的是實現(xiàn)一個簡單的餅狀統(tǒng)計圖,效果如下:

  

特點:

1.使用非常方便,可放在xml布局文件中,然后在代碼中設(shè)置內(nèi)容,即:

PieChartView pieChartView = (PieChartView) findViewById(R.id.pie_chart);
PieChartView.PieItemBean[] items = new PieChartView.PieItemBean[]{
    new PieChartView.PieItemBean("娛樂", 200),
    new PieChartView.PieItemBean("旅行", 100),
    new PieChartView.PieItemBean("學(xué)習(xí)", 120),
    new PieChartView.PieItemBean("人際關(guān)系", 160),
    new PieChartView.PieItemBean("交通", 100),
    new PieChartView.PieItemBean("餐飲", 480)
};
pieChartView.setPieItems(items);

2.條目數(shù)量,大小及折線位置,長度均自適應(yīng)。左側(cè)條目往左側(cè)劃線,右側(cè)條目往右側(cè)劃線,文字描述與百分比居中對齊,并且文字“下劃線”與文字長度自適應(yīng)。對于很小的條目,將自動將折線延長以盡可能避免文字遮蓋

核心代碼:PieChartView.Java:

public class PieChartView extends View {
  private int screenW, screenH;
  /**
   * The paint to draw text, pie and line.
   */
  private Paint textPaint, piePaint, linePaint;
  /**
   * The center and the radius of the pie.
   */
  private int pieCenterX, pieCenterY, pieRadius;
  /**
   * The oval to draw the oval in.
   */
  private RectF pieOval;
  private float smallMargin;
  private int[] mPieColors = new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA, Color.CYAN};
  private PieItemBean[] mPieItems;
  private float totalValue;
  public PieChartView(Context context) {
    super(context);
    init(context);
  }
  public PieChartView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
  }
  public PieChartView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
  }
  private void init(Context context) {
    //init screen
    screenW = ScreenUtils.getScreenW(context);
    screenH = ScreenUtils.getScreenH(context);
    pieCenterX = screenW / 2;
    pieCenterY = screenH / 3;
    pieRadius = screenW / 4;
    smallMargin = ScreenUtils.dp2px(context, 5);
    pieOval = new RectF();
    pieOval.left = pieCenterX - pieRadius;
    pieOval.top = pieCenterY - pieRadius;
    pieOval.right = pieCenterX + pieRadius;
    pieOval.bottom = pieCenterY + pieRadius;
    //The paint to draw text.
    textPaint = new Paint();
    textPaint.setAntiAlias(true);
    textPaint.setTextSize(ScreenUtils.dp2px(context, 16));
    //The paint to draw circle.
    piePaint = new Paint();
    piePaint.setAntiAlias(true);
    piePaint.setStyle(Paint.Style.FILL);
    //The paint to draw line to show the concrete text
    linePaint = new Paint();
    linePaint.setAntiAlias(true);
    linePaint.setStrokeWidth(ScreenUtils.dp2px(context, 1));
  }
  //The degree position of the last item arc's center.
  private float lastDegree = 0;
  //The count of the continues 'small' item.
  private int addTimes = 0;
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mPieItems != null && mPieItems.length > 0) {
      float start = 0.0f;
      for (int i = 0; i < mPieItems.length; i++) {
        //draw pie
        piePaint.setColor(mPieColors[i % mPieColors.length]);
        float sweep = mPieItems[i].getItemValue() / totalValue * 360;
        canvas.drawArc(pieOval, start, sweep, true, piePaint);
        //draw line away from the pie
        float radians = (float) ((start + sweep / 2) / 180 * Math.PI);
        float lineStartX = pieCenterX + pieRadius * 0.7f * (float) (Math.cos(radians));
        float lineStartY = pieCenterY + pieRadius * 0.7f * (float) (Math.sin(radians));
        float lineStopX, lineStopY;
        float rate;
        if (getOffset(start + sweep / 2) > 60) {
          rate = 1.3f;
        } else if (getOffset(start + sweep / 2) > 30) {
          rate = 1.2f;
        } else {
          rate = 1.1f;
        }
        //If the item is very small, make the text further away from the pie to avoid being hided by other text.
        if (start + sweep / 2 - lastDegree < 30) {
          addTimes++;
          rate += 0.2f * addTimes;
        } else {
          addTimes = 0;
        }
        lineStopX = pieCenterX + pieRadius * rate * (float) (Math.cos(radians));
        lineStopY = pieCenterY + pieRadius * rate * (float) (Math.sin(radians));
        canvas.drawLine(lineStartX, lineStartY, lineStopX, lineStopY, linePaint);
        //write text
        String itemTypeText = mPieItems[i].getItemType();
        String itemPercentText = Utility.formatFloat(mPieItems[i].getItemValue() / totalValue * 100) + "%";
        float itemTypeTextLen = textPaint.measureText(itemTypeText);
        float itemPercentTextLen = textPaint.measureText(itemPercentText);
        float lineTextWidth = Math.max(itemTypeTextLen, itemPercentTextLen);
        float textStartX = lineStopX;
        float textStartY = lineStopY - smallMargin;
        float percentStartX = lineStopX;
        float percentStartY = lineStopY + textPaint.getTextSize();
        if (lineStartX > pieCenterX) {
          textStartX += (smallMargin + Math.abs(itemTypeTextLen - lineTextWidth) / 2);
          percentStartX += (smallMargin + Math.abs(itemPercentTextLen - lineTextWidth) / 2);
        } else {
          textStartX -= (smallMargin + lineTextWidth - Math.abs(itemTypeTextLen - lineTextWidth) / 2);
          percentStartX -= (smallMargin + lineTextWidth - Math.abs(itemPercentTextLen - lineTextWidth) / 2);
        }
        canvas.drawText(itemTypeText, textStartX, textStartY, textPaint);
        //draw percent text
        canvas.drawText(itemPercentText, percentStartX, percentStartY, textPaint);
        //draw text underline
        float textLineStopX = lineStopX;
        if (lineStartX > pieCenterX) {
          textLineStopX += (lineTextWidth + smallMargin * 2);
        } else {
          textLineStopX -= (lineTextWidth + smallMargin * 2);
        }
        canvas.drawLine(lineStopX, lineStopY, textLineStopX, lineStopY, linePaint);
        lastDegree = start + sweep / 2;
        start += sweep;
      }
    }
  }
  public PieItemBean[] getPieItems() {
    return mPieItems;
  }
  public void setPieItems(PieItemBean[] pieItems) {
    this.mPieItems = pieItems;
    totalValue = 0;
    for (PieItemBean item : mPieItems) {
      totalValue += item.getItemValue();
    }
    invalidate();
  }
  private float getOffset(float radius) {
    int a = (int) (radius % 360 / 90);
    switch (a) {
      case 0:
        return radius;
      case 1:
        return 180 - radius;
      case 2:
        return radius - 180;
      case 3:
        return 360 - radius;
    }
    return radius;
  }
  static class PieItemBean {
    private String itemType;
    private float itemValue;
    PieItemBean(String itemType, float itemValue) {
      this.itemType = itemType;
      this.itemValue = itemValue;
    }
    public String getItemType() {
      return itemType;
    }
    public void setItemType(String itemType) {
      this.itemType = itemType;
    }
    public float getItemValue() {
      return itemValue;
    }
    public void setItemValue(float itemValue) {
      this.itemValue = itemValue;
    }
  }
}

完整實例代碼點擊此處本站下載。

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)

希望本文所述對大家Android程序設(shè)計有所幫助。

相關(guān)文章

  • Android中對xml文件解析的3種方式總結(jié)

    Android中對xml文件解析的3種方式總結(jié)

    這篇文章主要給大家介紹了關(guān)于Android中對xml文件解析的3種方式,分別是 Dom 、 SAX 和 dom4j,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02
  • AndroidHttpClient詳解及調(diào)用示例

    AndroidHttpClient詳解及調(diào)用示例

    本文給大家介紹AndroidHttpClient結(jié)構(gòu)、使用方式及調(diào)用示例詳解,需要的朋友可以參考下
    2015-10-10
  • 詳解Android Studio正式簽名進行調(diào)試的實現(xiàn)步驟

    詳解Android Studio正式簽名進行調(diào)試的實現(xiàn)步驟

    這篇文章主要介紹了詳解Android Studio正式簽名進行調(diào)試的實現(xiàn)步驟的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Android音樂播放器簡單實現(xiàn)案例

    Android音樂播放器簡單實現(xiàn)案例

    我們平時長時間打代碼的時候肯定會感到疲憊和乏味,這個時候一邊播放自己喜歡的音樂,一邊繼續(xù)打代碼,心情自然也愉快很多。音樂帶給人的聽覺享受是無可比擬的,動聽的音樂可以愉悅?cè)说纳硇?,讓人更加積極地去熱愛生活,這篇文章主要介紹了Android音樂播放器簡單實現(xiàn)案例
    2022-12-12
  • Eclipse NDK遷移到Android Studio的方法示例

    Eclipse NDK遷移到Android Studio的方法示例

    本篇文章主要介紹了Eclipse NDK遷移到Android Studio的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Android組件banner實現(xiàn)左右滑屏效果

    Android組件banner實現(xiàn)左右滑屏效果

    這篇文章主要為大家詳細介紹了Android組件banner實現(xiàn)左右滑屏效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • 淺析KJFrameForAndroid框架如何高效加載Bitmap

    淺析KJFrameForAndroid框架如何高效加載Bitmap

    Bitmap是Android系統(tǒng)中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進行圖像剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件。本文主要是從KJFrameForAndroid框架中分析高效加載Bitmap的方法
    2014-07-07
  • 使用CursorLoader異步加載數(shù)據(jù)

    使用CursorLoader異步加載數(shù)據(jù)

    這篇文章主要為大家詳細介紹了使用CursorLoader異步加載數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 詳解Android跨進程IPC通信AIDL機制原理

    詳解Android跨進程IPC通信AIDL機制原理

    本篇文章主要介紹了詳解Android跨進程IPC通信AIDL機制原理,詳細的介紹了AIDL的概念和使用,具有一定的參考價值,有興趣的可以了解一下
    2018-01-01
  • Android 判斷程序在前臺運行還是后臺運行

    Android 判斷程序在前臺運行還是后臺運行

    本文主要介紹了Android 判斷程序在前臺運行還是后臺運行的方法。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04

最新評論