最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2017年02月20日 17:11:35   作者:CSU_IceLee  
本篇文章主要介紹了Android自定義View——扇形統(tǒng)計圖的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Android 扇形統(tǒng)計圖

先看看效果:

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

自定義View

定義成員變量

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

  private int centerX, centerY;//中心坐標

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

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

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

  //顏色 默認的顏色
  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;//半徑 在畫圖時初始化

測量寬高

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

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

  }

畫圖

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  //無數(shù)據 直接返回
  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);
  }

  //畫各個扇形
  drawCircle(canvas);

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

}

畫扇形

一個圓形統(tǒng)計圖是由許多個扇形組成的,我們根據數(shù)據計算出每個扇形的角度即可。注意,畫弧度的時候,角度是順時針變大的!即與我們平時的坐標是反過來的

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

    int start = 0;//扇形開始的角度
    for (int i = 0; i < (maxNum<datas.length?maxNum:datas.length); i++) {
      float angles = (float) ((datas[i] * 1.0f /total) * 360);//計算扇形的角度
      mPaint.setColor(mColors[i%mColors.length]);//顏色
      canvas.drawArc(rect,start,angles,true,mPaint);//畫扇形
      start += angles;//下一個扇形開始的角度
    }

    //畫"其他"部分 即圖中灰色的部分
    rest =0;//保存其他部分的value
    for(int i=maxNum;i<datas.length;i++){
      rest+=datas[i];
    }
    float angles = (float) 360 - start;//角度
    mPaint.setColor(Color.GRAY);
    canvas.drawArc(rect,start,angles,true,mPaint);

  }

畫線條和文字

主要是計算各個點的坐標很煩

這里我畫出一個圖 大家把代碼和圖對照理解一下

 

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

    //如果數(shù)據集過大 那么要合并到其他
    for (int i = 0; i < (maxNum < datas.length ? maxNum : datas.length); i++) {
      float angles = (float) ((datas[i] * 1.0f / total) * 360);
      //畫線條和文字
      drawLine(canvas, start, angles, texts[i], mColors[i % mColors.length]);
      start += angles;
    }
    //畫其他部分的線條和文字
    if (start < 360)//如果start小于360 說明有其他部分
      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
    );
    //畫橫線
    int dx;//判斷橫線是畫在左邊還是右邊
    int endX;
    if (stopX > 0) {
      endX = (centerX - getPaddingRight() - 20);
    } else {
      endX = (-centerX + getPaddingLeft() + 20);
    }
    //畫橫線
    canvas.drawLine(stopX, stopY,
        endX, stopY, mPaint
    );
    dx = (int) (endX - stopX);

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

    //測量百分比大小
    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;
    //畫百分比
    canvas.drawText(percentage, 0, percentage.length(), dx > 0 ? stopX + offset : stopX - w - offset, stopY - 5, mTextPaint);

  }

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

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

我使用了一個內部抽象類來實現(xiàn)數(shù)據綁定的:

  public abstract class ArcViewAdapter<T> {

    public void setData(List<T> 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();//請求重繪
    }

    //通過傳來的數(shù)據集的某個元素 得到具體的數(shù)字
    public abstract double getValue(T t);

    //通過傳來的數(shù)據集的某個元素 得到具體的描述
    public abstract String getText(T t);
  }

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

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

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

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

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

demo下載地址:SectorDiagram_jb51.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android實現(xiàn)簡易登陸注冊邏輯的實例代碼

    Android實現(xiàn)簡易登陸注冊邏輯的實例代碼

    在android的應用中越來越多的包含了網絡互動功能,這就帶來了注冊,登陸賬號功能,這篇文章主要給大家介紹了關于Android實現(xiàn)簡易登陸注冊邏輯的相關資料,需要的朋友可以參考下
    2021-06-06
  • android實現(xiàn)圖片上傳功能(springMvc)

    android實現(xiàn)圖片上傳功能(springMvc)

    這篇文章主要為大家詳細介紹了android結合springMvc實現(xiàn)圖片上傳的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android實現(xiàn)短視頻畫心效果

    Android實現(xiàn)短視頻畫心效果

    這篇文章主要為大家詳細介紹了Android實現(xiàn)短視頻畫心效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Android實現(xiàn)短信、微信、微博分享功能

    Android實現(xiàn)短信、微信、微博分享功能

    微信、微博分享功能大家都體驗過吧,非常方便我們的生活,下面通過本文給大家介紹Android實現(xiàn)短信、微信、微博分享功能,需要的朋友參考下吧
    2017-12-12
  • Android TextView實現(xiàn)帶鏈接文字事件監(jiān)聽的三種常用方式示例

    Android TextView實現(xiàn)帶鏈接文字事件監(jiān)聽的三種常用方式示例

    這篇文章主要介紹了Android TextView實現(xiàn)帶鏈接文字事件監(jiān)聽的方法,結合實例形式分析了鏈接跳轉、setMovementMethod及布局屬性設置三種常用的實現(xiàn)方式,需要的朋友可以參考下
    2017-08-08
  • 注解處理器(APT)是什么

    注解處理器(APT)是什么

    APT是JDK提供的工具,用于在編譯階段未生成class之前對源碼中的注解進行掃描和處理,獲取到注解后可以使用原始方法與JavaPoet生成Java代碼,這篇文章主要介紹了注解處理器(APT)是什么?需要的朋友可以參考
    2023-02-02
  • Android?NDK開發(fā)(C語言--聯(lián)合體與枚舉)

    Android?NDK開發(fā)(C語言--聯(lián)合體與枚舉)

    這篇文章主要介紹了Android?NDK開發(fā)C語言聯(lián)合體與枚舉,共用體是一種特殊的數(shù)據類型,允許您在相同的內存位置存儲不同的數(shù)據類型。您可以定義一個帶有多成員的共用體,但是任何時候只能有一個成員帶有值。下面詳細介紹該內容,需要的朋友可以參考一下
    2021-12-12
  • Android開發(fā)實現(xiàn)撥打電話與發(fā)送信息的方法分析

    Android開發(fā)實現(xiàn)撥打電話與發(fā)送信息的方法分析

    這篇文章主要介紹了Android開發(fā)實現(xiàn)撥打電話與發(fā)送信息的方法,結合實例形式分析了Android撥打電話及發(fā)送信息相關布局、功能實現(xiàn)及權限控制操作技巧,需要的朋友可以參考下
    2017-12-12
  • 深入學習Android中的Intent

    深入學習Android中的Intent

    深入學習Android中的Intent,Intent提供了一種通用的消息系統(tǒng),它允許在你的應用程序見傳遞Intent來執(zhí)行動作和產生事件,對Intent感興趣的小伙伴們可以參考一下
    2015-12-12
  • Android設置拍照或者上傳本地圖片的示例

    Android設置拍照或者上傳本地圖片的示例

    本篇文章主要介紹了Android設置拍照或者上傳本地圖片示例,可以拍照或者上傳本地文件,有需要的可以了解一下。
    2016-11-11

最新評論

密山市| 洛扎县| 云和县| 丰台区| 罗平县| 山阴县| 永泰县| 黄龙县| 嘉禾县| 大冶市| 本溪| 石景山区| 岳西县| 阳高县| 同江市| 泰和县| 晋中市| 广丰县| 屏东市| 苏尼特左旗| 临安市| 巴青县| 静海县| 易门县| 南阳市| 多伦县| 南部县| 会宁县| 独山县| 漳浦县| 台前县| 马山县| 淳化县| 调兵山市| 孝昌县| 金川县| 新龙县| 红原县| 碌曲县| 永丰县| 山阴县|