国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

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

2019-10-23 19:49:51
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

本例的目的是實(shí)現(xiàn)一個(gè)簡(jiǎn)單的餅狀統(tǒng)計(jì)圖,效果如下:

Android,canvas,繪制,餅狀,統(tǒng)計(jì)圖 Android,canvas,繪制,餅狀,統(tǒng)計(jì)圖 Android,canvas,繪制,餅狀,統(tǒng)計(jì)圖

特點(diǎn):

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

PieChartView pieChartView = (PieChartView) findViewById(R.id.pie_chart);PieChartView.PieItemBean[] items = new PieChartView.PieItemBean[]{    new PieChartView.PieItemBean("娛樂(lè)", 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ù)量,大小及折線位置,長(zhǎng)度均自適應(yīng)。左側(cè)條目往左側(cè)劃線,右側(cè)條目往右側(cè)劃線,文字描述與百分比居中對(duì)齊,并且文字“下劃線”與文字長(zhǎng)度自適應(yīng)。對(duì)于很小的條目,將自動(dòng)將折線延長(zhǎ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;    }  }}

完整實(shí)例代碼點(diǎn)擊此處本站下載。

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


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 关岭| 玉林市| 田东县| 桂平市| 江城| 阿勒泰市| 肃北| 洛阳市| 吉水县| 阿鲁科尔沁旗| 济南市| 东乡县| 中宁县| 临高县| 苏尼特左旗| 浦北县| 巴南区| 公主岭市| 墨竹工卡县| 株洲市| 集贤县| 北宁市| 横山县| 麻城市| 靖江市| 进贤县| 婺源县| 聊城市| 青海省| 兴化市| 仁化县| 乌兰察布市| 建德市| 石家庄市| 黄石市| 兴业县| 日喀则市| 晋江市| 饶平县| 如皋市| 屯昌县|