android 手把手教你自定义view(一)--雷达图模仿

1.先看一下我们要绘制的目标图

android 手把手教你自定义view(一)--雷达图模仿_第1张图片

思路:

1.绘制多边形

2.绘制顶点文字

3.绘制覆盖区域

(一)绘制多边形

android 手把手教你自定义view(一)--雷达图模仿_第2张图片

/**
 * 自定义雷达view
 * @author DEV-81
 * @version 1.0
 */

public class CustomRadarView extends View{
    private Paint mPaint; //多边形边框
    private int centerX=0;
    private int centerY=0;
    private int count=6;//多边形的个数
    private Path mPath;//绘制多边形的path
    private float radius=0;//半径
    private float currentR=0;//是蜘蛛丝之间的间距
    //正多边形两条边的夹角
    private float angle = (float) (Math.PI*2/count);
    public CustomRadarView(Context context) {
        this(context,null);
    }

    public CustomRadarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 初始化
     * */
    private void init() {
        mPaint=new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(1);
        mPath=new Path();
    }

    /**
     * 获取view的宽和高,并做相关的设置
     * */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        centerX=w/2;
        centerY=h/2;
        radius = Math.min(h, w)/2*0.8f;
        invalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawPolygon(canvas);
    }

    /**
     * 绘制多边形
     * @param canvas
     * */
    private void drawPolygon(Canvas canvas) {
//        是蜘蛛丝之间的间距
        currentR=radius/(count-1);
        
        for (int i = 0; i < count; i++) {
            //获取每一个多边形外切圆的半径
            float r=currentR*i;
            mPath.reset();
            
            //绘制一个多边形的多条边
            for (int j = 0; j < count; j++) {
                if(j==0){
                    //每一圈设置起点
                    mPath.moveTo(centerX+r,centerY);
                }else{
                    //根据半径,计算出蜘蛛丝上每个点的坐标
                    float x= (float) (centerX+r*Math.cos(angle*j));
                    float y= (float) (centerY+r*Math.sin(angle*j));
                    mPath.lineTo(x,y);

                }
            }
            
            mPath.close();
            canvas.drawPath(mPath,mPaint);
        }

    }
}

显示效果如下:

android 手把手教你自定义view(一)--雷达图模仿_第3张图片

接下来需要绘制中心到末端的直线

/**
 * 绘制中心到多边形的各个顶点的连线
 * @param canvas
 * */
private void drawLines(Canvas canvas) {
    Path path=new Path();
    for (int i = 0; i < count; i++) {
        //每一次重置path,将起点移到中心
        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,mPaint);
    }
}

android 手把手教你自定义view(一)--雷达图模仿_第4张图片

绘制顶端文字

/**
 * 绘制文字
 * @param canvas
 * */
private void drawText(Canvas canvas) {
    Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
    float fontHeight = fontMetrics.descent - fontMetrics.ascent;
    for (int i = 0; i < count; 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){ //第四象限
             //文字绘制在顶点的右边
                canvas.drawText(titles[i],x,y,mTextPaint);
         }else if(angle*i>Math.PI/2 && angle*i<=Math.PI){ //第三象限
             //文字绘制在顶点的左边 ,也就是顶点坐标然后像左侧偏移一部分距离
             float offset = mTextPaint.measureText(titles[i]);
             canvas.drawText(titles[i],x-offset,y,mTextPaint);
         }else if(angle*i>Math.PI && angle*i<=3*Math.PI/2){ //第二象限
             //文字绘制在顶点的左边 ,也就是顶点坐标然后像左侧偏移一部分距离
             float offset = mTextPaint.measureText(titles[i]);
             canvas.drawText(titles[i],x-offset,y,mTextPaint);
         }else if(angle*i>3*Math.PI/2 && angle*i<2*Math.PI){//第一象限
             //文字绘制在顶点的右边
             canvas.drawText(titles[i],x,y,mTextPaint);
         }
    }
}

效果图如下:

android 手把手教你自定义view(一)--雷达图模仿_第5张图片

知识点扩展:

1.在android 中坐标系与数学中坐标系的区别:

android 手把手教你自定义view(一)--雷达图模仿_第6张图片

android 手把手教你自定义view(一)--雷达图模仿_第7张图片

android 手把手教你自定义view(一)--雷达图模仿_第8张图片


你可能感兴趣的:(自定义view)