<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android雷達(dá)圖(蜘蛛網(wǎng)圖)繪制

          共 1978字,需瀏覽 4分鐘

           ·

          2022-03-23 11:12

          最近因?yàn)轫?xiàng)目需求,要實(shí)現(xiàn)一款雷達(dá)圖來表示用戶的各種成就值。


          雷達(dá)圖的繪制很簡(jiǎn)單,只要思路清晰按部就班的繪制就可以了,其中使用得最多,是路徑path類的使用,使用這個(gè)類可以讓我們更加方便地繪制出正多邊形等效果。


          效果圖如下:

          使用方式


          使用方式很簡(jiǎn)單,只要在布局文件里面,直接使用這個(gè)控件就好了,記得給它設(shè)置一個(gè)合適的具體的大小。


          另外可以控制繪制的是多少邊形,通過提供的一些public方法,可以設(shè)置畫筆顏色等,當(dāng)然大家也可以按照自己的需求去修改啦。

              //設(shè)置標(biāo)題    public void setTitles(String[] titles) {        this.titles = titles;    }
          //設(shè)置數(shù)值 public void setData(double[] data) { this.data = data; }
          //設(shè)置最大數(shù)值 public void setMaxValue(float maxValue) { this.maxValue = maxValue; }
          //設(shè)置蜘蛛網(wǎng)顏色 public void setMainPaintColor(int color){ mainPaint.setColor(color); }
          //設(shè)置標(biāo)題顏色 public void setTextPaintColor(int color){ textPaint.setColor(color); }
          //設(shè)置覆蓋局域顏色 public void setValuePaintColor(int color){ valuePaint.setColor(color); }


          具體實(shí)現(xiàn)


          1、獲得布局中心


          我們?cè)趏nSizeChanged(int w, int h, int oldw, int oldh)方法里面,根據(jù)View的長寬,獲取整個(gè)布局的中心坐標(biāo),因?yàn)檎麄€(gè)雷達(dá)都是以整個(gè)中心開始繪制的。

          public class RadarView extends View {    private int count = 6;                //數(shù)據(jù)個(gè)數(shù)      private float angle = (float) (Math.PI*2/count);         private float radius;                   //網(wǎng)格最大半徑      private int centerX;                  //中心X      private int centerY;                  //中心Y      private String[] titles = {"a","b","c","d","e","f"};    private double[] data = {100,60,60,60,100,50,10,20}; //各維度分值      private float maxValue = 100;             //數(shù)據(jù)最大值    private Paint mainPaint;                //雷達(dá)區(qū)畫筆      private Paint valuePaint;               //數(shù)據(jù)區(qū)畫筆      private Paint textPaint;                //文本畫筆          ...    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        radius = Math.min(h, w)/2*0.9f;        //中心坐標(biāo)        centerX = w/2;        centerY = h/2;        postInvalidate();        super.onSizeChanged(w, h, oldw, oldh);    }    ...}


          2、繪制蜘蛛網(wǎng)絡(luò)

               /**     * 繪制正多邊形     */    private void drawPolygon(Canvas canvas){        Path path = new Path();        float r = radius/(count-1);//r是蜘蛛絲之間的間距        for(int i=1;i            float curR = r*i;//當(dāng)前半徑            path.reset();            for(int j=0;j                if(j==0){                    path.moveTo(centerX+curR,centerY);                }else{                    //根據(jù)半徑,計(jì)算出蜘蛛絲上每個(gè)點(diǎn)的坐標(biāo)                    float x = (float) (centerX+curR*Math.cos(angle*j));                    float y = (float) (centerY+curR*Math.sin(angle*j));                    path.lineTo(x,y);                }            }            path.close();//閉合路徑            canvas.drawPath(path, mainPaint);        }    }

          3、繪制從中心到末端的直線


          同樣根據(jù)半徑,計(jì)算出每個(gè)末端坐標(biāo)

               /**     * 繪制直線     */    private void drawLines(Canvas canvas){        Path path = new Path();        for(int i=0;i            path.reset();            path.moveTo(centerX, centerY);            float x = (float) (centerX+radius*Math.cos(angle*i));            float y = (float) (centerY+radius*Math.sin(angle*i));            path.lineTo(x, y);            canvas.drawPath(path, mainPaint);        }    }


          4、繪制文本


          對(duì)于文本的繪制,首先要找到末端的坐標(biāo),由于末端和文本有一定距離,給每個(gè)末端加上這個(gè)距離以后,再繪制文本。


          另外,當(dāng)文本在左邊時(shí),由于不希望文本和蜘蛛網(wǎng)交叉,我們可以先計(jì)算出文本的長度,然后使起始繪制坐標(biāo)向左偏移這個(gè)長度。

               /**     * 繪制文字     * @param canvas     */    private void drawText(Canvas canvas){        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();        float fontHeight = fontMetrics.descent - fontMetrics.ascent;        for(int i=0;i            float x = (float) (centerX+(radius+fontHeight/2)*Math.cos(angle*i));            float y = (float) (centerY+(radius+fontHeight/2)*Math.sin(angle*i));            if(angle*i>=0&&angle*i<=Math.PI/2){//第4象限                canvas.drawText(titles[i], x,y,textPaint);            }else if(angle*i>=3*Math.PI/2&&angle*i<=Math.PI*2){//第3象限                canvas.drawText(titles[i], x,y,textPaint);            }else if(angle*i>Math.PI/2&&angle*i<=Math.PI){//第2象限                float dis = textPaint.measureText(titles[i]);//文本長度                canvas.drawText(titles[i], x-dis,y,textPaint);            }else if(angle*i>=Math.PI&&angle*i<3*Math.PI/2){//第1象限                float dis = textPaint.measureText(titles[i]);//文本長度                canvas.drawText(titles[i], x-dis,y,textPaint);            }        }    }

          5、繪制覆蓋區(qū)域


          覆蓋區(qū)域,只要使用path記錄下坐標(biāo)點(diǎn),然后設(shè)

          valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);


          使path包圍區(qū)域被填充

          ?????/**     * 繪制區(qū)域     * @param canvas     */    private void drawRegion(Canvas canvas){        Path path = new Path();        valuePaint.setAlpha(255);        for(int i=0;i            double percent = data[i]/maxValue;            float x = (float) (centerX+radius*Math.cos(angle*i)*percent);            float y = (float) (centerY+radius*Math.sin(angle*i)*percent);            if(i==0){                path.moveTo(x, centerY);            }else{                path.lineTo(x,y);            }            //繪制小圓點(diǎn)            canvas.drawCircle(x,y,10,valuePaint);        }        valuePaint.setStyle(Paint.Style.STROKE);        canvas.drawPath(path, valuePaint);        valuePaint.setAlpha(127);        //繪制填充區(qū)域        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);        canvas.drawPath(path, valuePaint);    }


          本篇文章主要是path類的使用,另外這個(gè)控件沒有做較好的屏幕適配,大家可以根據(jù)自己的需要修改。


          到這里就結(jié)束啦。

          瀏覽 183
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品黄色在线观看 | 日日夜夜无码 | 黄色视屏在线观看 | 欧美精品成人无码 | 青青国产精品视频 |