真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android自定義View——扇形統(tǒng)計(jì)圖的實(shí)現(xiàn)代碼

Android 扇形統(tǒng)計(jì)圖

成都創(chuàng)新互聯(lián)主營(yíng)開(kāi)魯網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都APP應(yīng)用開(kāi)發(fā),開(kāi)魯h5成都小程序開(kāi)發(fā)搭建,開(kāi)魯網(wǎng)站營(yíng)銷(xiāo)推廣歡迎開(kāi)魯?shù)鹊貐^(qū)企業(yè)咨詢(xún)

先看看效果:

看上去如果覺(jué)得還行就繼續(xù)往下看吧!

Android自定義View——扇形統(tǒng)計(jì)圖的實(shí)現(xiàn)代碼

Android自定義View——扇形統(tǒng)計(jì)圖的實(shí)現(xiàn)代碼

自定義View

定義成員變量

  private int mHeight, mWidth;//寬高
  private Paint mPaint;//扇形的畫(huà)筆
  private Paint mTextPaint;//畫(huà)文字的畫(huà)筆

  private int centerX, centerY;//中心坐標(biāo)

  //"其他"的value
  //扇形圖分成太多快 所以要合并一部分為其他 即圖中灰色部分
  private double rest;

  private int maxNum = 5;//扇形圖的最大塊數(shù) 超過(guò)的item就合并到其他

  String others = "其他";//“其他”塊要顯示的文字
  double total;//數(shù)據(jù)的總和 
  double[] datas;//數(shù)據(jù)集
  String[] texts;//每個(gè)數(shù)據(jù)對(duì)應(yīng)的文字集

  //顏色 默認(rèn)的顏色
  private int[] mColors = {
      Color.parseColor("#FF4081"), Color.parseColor("#ffc0cb"),
      Color.parseColor("#00ff00"), Color.parseColor("#0066ff"), Color.parseColor("#ffee00")
  };

  private int mTextSize;//文字大小 單位:像素

  private int radius = 1000;//半徑 在畫(huà)圖時(shí)初始化

測(cè)量寬高

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    //獲取寬高 不要設(shè)置wrap_content
    mHeight = MeasureSpec.getSize(heightMeasureSpec);
    mWidth = MeasureSpec.getSize(widthMeasureSpec);

  }

畫(huà)圖

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  //無(wú)數(shù)據(jù) 直接返回
  if (datas == null || datas.length == 0) return;

  centerX = (getRight() - getLeft()) / 2;
  centerY = (getBottom() - getTop()) / 2;
  int min = mHeight > mWidth ? mWidth : mHeight;
  if (radius > min / 2) {
    radius = (int) ((min - getPaddingTop() - getPaddingBottom()) / 3.5);
  }

  //畫(huà)各個(gè)扇形
  drawCircle(canvas);

  //畫(huà)線與文字
  drawLineAndText(canvas);

}

畫(huà)扇形

一個(gè)圓形統(tǒng)計(jì)圖是由許多個(gè)扇形組成的,我們根據(jù)數(shù)據(jù)計(jì)算出每個(gè)扇形的角度即可。注意,畫(huà)弧度的時(shí)候,角度是順時(shí)針變大的!即與我們平時(shí)的坐標(biāo)是反過(guò)來(lái)的

  //畫(huà)扇形
  private void drawCircle(Canvas canvas) {
    int centerX =( getRight() - getLeft() )/2;//中點(diǎn)
    int centerY = ( getBottom() - getTop()) /2;
    RectF rect = new RectF((float) (centerX - radius), centerY-radius,
        centerX+radius,centerY+radius);//圓形區(qū)域

    int start = 0;//扇形開(kāi)始的角度
    for (int i = 0; i < (maxNum

畫(huà)線條和文字

主要是計(jì)算各個(gè)點(diǎn)的坐標(biāo)很煩

這里我畫(huà)出一個(gè)圖 大家把代碼和圖對(duì)照理解一下

Android自定義View——扇形統(tǒng)計(jì)圖的實(shí)現(xiàn)代碼

 

//畫(huà)線與文字
  private void drawLineAndText(Canvas canvas) {
    int start = 0;
    //平移畫(huà)布到中心 所以下面的坐標(biāo)是從中點(diǎn)開(kāi)始算起的
    canvas.translate(centerX, centerY);
    mPaint.setStrokeWidth(4);//線條寬度

    //如果數(shù)據(jù)集過(guò)大 那么要合并到其他
    for (int i = 0; i < (maxNum < datas.length ? maxNum : datas.length); i++) {
      float angles = (float) ((datas[i] * 1.0f / total) * 360);
      //畫(huà)線條和文字
      drawLine(canvas, start, angles, texts[i], mColors[i % mColors.length]);
      start += angles;
    }
    //畫(huà)其他部分的線條和文字
    if (start < 360)//如果start小于360 說(shuō)明有其他部分
      drawLine(canvas, start, 360 - start, others, Color.GRAY);

  }

  private void drawLine(Canvas canvas, int start, float angles, String text, int color) {
    mPaint.setColor(color);
    float stopX, stopY;
    stopX = (float) ((radius + 40) * Math.cos((2 * start + angles) / 2 * Math.PI / 180));
    stopY = (float) ((radius + 40) * Math.sin((2 * start + angles) / 2 * Math.PI / 180));

    canvas.drawLine((float) ((radius - 20) * Math.cos((2 * start + angles) / 2 * Math.PI / 180)),
        (float) ((radius - 20) * Math.sin((2 * start + angles) / 2 * Math.PI / 180)),
        stopX, stopY, mPaint
    );
    //畫(huà)橫線
    int dx;//判斷橫線是畫(huà)在左邊還是右邊
    int endX;
    if (stopX > 0) {
      endX = (centerX - getPaddingRight() - 20);
    } else {
      endX = (-centerX + getPaddingLeft() + 20);
    }
    //畫(huà)橫線
    canvas.drawLine(stopX, stopY,
        endX, stopY, mPaint
    );
    dx = (int) (endX - stopX);

    //測(cè)量文字大小
    Rect rect = new Rect();
    mTextPaint.getTextBounds(text, 0, text.length(), rect);
    int w = rect.width();
    int h = rect.height();
    int offset = 20;//文字在橫線的偏移量
    //畫(huà)文字 文字的Y坐標(biāo)值的是文字底部的Y坐標(biāo)
    canvas.drawText(text, 0, text.length(), dx > 0 ? stopX + offset : stopX - w - offset, stopY + h, mTextPaint);

    //測(cè)量百分比大小
    String percentage = angles / 3.60 + "";
    percentage = percentage.substring(0, percentage.length() > 4 ? 4 : percentage.length()) + "%";
    mTextPaint.getTextBounds(percentage, 0, percentage.length(), rect);
    w = rect.width() - 10;
    //畫(huà)百分比
    canvas.drawText(percentage, 0, percentage.length(), dx > 0 ? stopX + offset : stopX - w - offset, stopY - 5, mTextPaint);

  }

這樣我們就已經(jīng)完成了繪制的工作了,接下來(lái)就是綁定數(shù)據(jù)啦!

大家只要把datas和texts填充好數(shù)據(jù)就可以啦,最好調(diào)用一下invalidate()方法請(qǐng)求重繪(如果已經(jīng)繪制了)。

我使用了一個(gè)內(nèi)部抽象類(lèi)來(lái)實(shí)現(xiàn)數(shù)據(jù)綁定的:

  public abstract class ArcViewAdapter {

    public void setData(List list) {
      datas = new double[list.size()];
      texts = new String[list.size()];
      for (int i = 0; i < list.size(); i++) {
        total += getValue(list.get(i));
        datas[i] = getValue(list.get(i));
        texts[i] = getText(list.get(i));
      }
      invalidate();//請(qǐng)求重繪
    }

    //通過(guò)傳來(lái)的數(shù)據(jù)集的某個(gè)元素 得到具體的數(shù)字
    public abstract double getValue(T t);

    //通過(guò)傳來(lái)的數(shù)據(jù)集的某個(gè)元素 得到具體的描述
    public abstract String getText(T t);
  }

在布局文件里面引用這個(gè)ArcView,然后在MainActivity中綁定數(shù)據(jù):

ArcView arcView = (ArcView) findViewById(R.id.arc);
    List times = new ArrayList<>();
    for (int i = 6; i > 0; i--) {
      Times t = new Times();//這個(gè)類(lèi)就只有兩個(gè)變量
      t.hour = i;
      t.text = "Number"+i;
      times.add(t);
    }

    //初始化適配器
    ArcView.ArcViewAdapter myAdapter = arcView.new ArcViewAdapter(){
      @Override
      public double getValue(Times times) {
        return times.hour;
      }

      @Override
      public String getText(Times times) {
        return times.text;
      }
    };
    myAdapter.setData(times);//綁定數(shù)據(jù)

大家可以設(shè)置各種setter以便在Activity中調(diào)用,來(lái)提高ArcView的靈活性,比如設(shè)置顏色、半徑、最大塊數(shù)等等。

demo下載地址:SectorDiagram_jb51.rar

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


網(wǎng)站名稱(chēng):Android自定義View——扇形統(tǒng)計(jì)圖的實(shí)現(xiàn)代碼
本文網(wǎng)址:http://weahome.cn/article/gjsjhe.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部