MainActivity

        //能力分析图        AbilityAnalysisView abilityView = (AbilityAnalysisView) findViewById(R.id.abilityAnalysisView_id)        analysisView.setDataCount(5)                    .setTitles(new String[]{"伤害", "防御", "攻速", "吸血", "助攻"})                    .setDatas(new float[]{170, 120, 90, 210, 120})//TODO 赋值相应的各维度分值,数据最大值maxValue在自定义View里可以更改                    .setColors(new  int[]{R.color.colorOrange4, R.color.colorOrange3, R.color.colorOrange2, R.color.colorOrange1, R.color.colorOrange5})                    .invalidate();//TODO 坑更新自定义View 调用OnDraw方法

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#000000">    <com.reachauto.abilityanalysis.AbilityAnalysisView        android:id="@+id/abilityAnalysisView_id"        android:layout_width="200dp"        android:layout_height="200dp"        android:layout_centerInParent="true" /></RelativeLayout>

AbilityAnalysisView

public class AbilityAnalysisView extends View {    //数据个数    private int dataCount = 5;    //每个角的弧度    private float radian = (float) (Math.PI * 2 / dataCount);    //雷达图半径    private float radius;    //中心X坐标    private int centerX;    //中心Y坐标    private int centerY;    //各维度标题    private String[] titles = {"伤害", "防御", "攻速", "吸血", "助攻"};    private int[] colors = {R.color.colorOrange4, R.color.colorOrange3, R.color.colorOrange2, R.color.colorOrange1, R.color.colorOrange5};    //各维度图标  //  private int[] icons = {R.mipmap.ic_performance, R.mipmap.ic_history, R.mipmap.ic_contacts,  //          R.mipmap.ic_predilection, R.mipmap.ic_identity};    //各维度分值    private float[] data = {170, 120, 90, 210, 150};    //数据最大值    private float maxValue = 210;    //雷达图与标题的间距    private int radarMargin = DensityUtils.dp2px(getContext(), 15);    //雷达区画笔    private Paint mainPaint;    //数据区画笔    private Paint valuePaint;    //分数画笔    private Paint scorePaint;    //标题画笔    private Paint titlePaint;    //图标画笔    private Paint iconPaint;    //分数大小    private int scoreSize = DensityUtils.dp2px(getContext(), 28);    //标题文字大小    private int titleSize = DensityUtils.dp2px(getContext(), 13);    public AbilityAnalysisView(Context context) {        this(context, null);    }    public AbilityAnalysisView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public AbilityAnalysisView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        mainPaint = new Paint();        mainPaint.setAntiAlias(true);        mainPaint.setStrokeWidth(0.3f);        mainPaint.setColor(Color.WHITE);        mainPaint.setStyle(Paint.Style.STROKE);        valuePaint = new Paint();        valuePaint.setAntiAlias(true);        valuePaint.setColor(Color.WHITE);        valuePaint.setAlpha(120);        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);        scorePaint = new Paint();        scorePaint.setAntiAlias(true);        scorePaint.setTextSize(scoreSize);        scorePaint.setColor(Color.WHITE);        scorePaint.setTextAlign(Paint.Align.CENTER);        scorePaint.setStyle(Paint.Style.FILL);        titlePaint = new Paint();        titlePaint.setAntiAlias(true);        titlePaint.setTextSize(titleSize);        titlePaint.setColor(Color.WHITE);        titlePaint.setStyle(Paint.Style.FILL);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        //雷达图半径        radius = Math.min(h, w) / 2 * 0.5f;        //中心坐标        centerX = w / 2;        centerY = h / 2;        postInvalidate();        super.onSizeChanged(w, h, oldw, oldh);    }    @Override    public void draw(Canvas canvas) {        super.draw(canvas);        drawPolygon(canvas);     //   drawLines(canvas);        drawRegion(canvas, colors);        drawScore(canvas);        drawTitle(canvas);    }    /**     * 绘制多边形     *     * @param canvas 画布     */    private void drawPolygon(Canvas canvas) {        Path path = new Path();//        for (int i = 0; i < dataCount; i++) {//            if (i == 0) {//                path.moveTo(getPoint(i).x, getPoint(i).y);//            } else {//                path.lineTo(getPoint(i).x, getPoint(i).y);//            }//        }////        //闭合路径//        path.close();//        canvas.drawPath(path, mainPaint);        Paint paint = new Paint();        paint.setAntiAlias(true);        paint.setStrokeWidth(7);        paint.setColor(getResources().getColor(R.color.colorGray));        paint.setStyle(Paint.Style.STROKE);        canvas.drawCircle(centerX,centerY,radius,paint);        paint.setStrokeWidth(3);        canvas.drawCircle(centerX,centerY,(radius * 9)/10, paint);        canvas.drawCircle(centerX,centerY,(radius * 8)/10, paint);        canvas.drawCircle(centerX,centerY,(radius * 7)/10, paint);    }    /**     * 绘制连接线     *     * @param canvas 画布     */    private void drawLines(Canvas canvas) {        Path path = new Path();        for (int i = 0; i < dataCount; i++) {            path.reset();            path.moveTo(centerX, centerY);            path.lineTo(getPoint(i).x, getPoint(i).y);            canvas.drawPath(path, mainPaint);        }    }    /**     * 获取雷达图上各个点的坐标     *     * @param position 坐标位置(右上角为0,顺时针递增)     * @return 坐标     */    private Point getPoint(int position) {        return getPoint(position, 0, 1);    }    /**     * 获取雷达图上各个点的坐标(包括维度标题与图标的坐标)     *     * @param position    坐标位置     * @param radarMargin 雷达图与维度标题的间距     * @param percent     覆盖区的的百分比     * @return 坐标     */    private Point getPoint(int position, int radarMargin, float percent) {        int x = 0;        int y = 0;        if (position == 0) {            x = (int) (centerX + (radius + radarMargin) * Math.sin(radian) * percent);            y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);        } else if (position == 1) {            x = (int) (centerX + (radius + radarMargin) * Math.sin(radian / 2) * percent);            y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);        } else if (position == 2) {            x = (int) (centerX - (radius + radarMargin) * Math.sin(radian / 2) * percent);            y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);        } else if (position == 3) {            x = (int) (centerX - (radius + radarMargin) * Math.sin(radian) * percent);            y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);        } else if (position == 4) {            x = centerX;            y = (int) (centerY - (radius + radarMargin) * percent);        }        return new Point(x, y);    }    /**     * 绘制覆盖区域     *     * @param canvas 画布     */    private void drawRegion(Canvas canvas, int[] colors) {        for (int i = 0; i < dataCount; ++i) {            Path path = new Path();            path.moveTo(centerX, centerY);            //计算百分比            float percent = data[i] / maxValue;            int x = getPoint(i, 0, percent).x;            int y = getPoint(i, 0, percent).y;            path.lineTo(x, y);            //计算百分比            if (dataCount == i+ 1){                float percent_next = data[0] / maxValue;                int x_next = getPoint(0, 0, percent_next).x;                int y_next = getPoint(0, 0, percent_next).y;                path.lineTo(x_next, y_next);                path.lineTo(centerX, centerX);            }else {                float percent_next = data[i + 1] / maxValue;                int x_next = getPoint(i+1, 0, percent_next).x;                int y_next = getPoint(i+1, 0, percent_next).y;                path.lineTo(x_next, y_next);                path.lineTo(centerX, centerX);            }            valuePaint.setColor(getResources().getColor(colors[i]));            path.close();           //绘制填充区域的边界            valuePaint.setStyle(Paint.Style.STROKE);            canvas.drawPath(path, valuePaint);            //绘制填充区域            valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);            canvas.drawPath(path, valuePaint);        }    }    private void drawRegion1(Canvas canvas) {        Path path = new Path();        for (int i = 0; i < dataCount; i++) {            //计算百分比            float percent = data[i] / maxValue;            int x = getPoint(i, 0, percent).x;            int y = getPoint(i, 0, percent).y;            if (i == 0) {                path.moveTo(x, y);            } else {                path.lineTo(x, y);            }        }        //绘制填充区域的边界        path.close();        valuePaint.setStyle(Paint.Style.STROKE);        canvas.drawPath(path, valuePaint);        //绘制填充区域        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);        canvas.drawPath(path, valuePaint);    }    /**     * 绘制标题     *     * @param canvas 画布     */    private void drawTitle(Canvas canvas) {        for (int i = 0; i < dataCount; i++) {            int x = getPoint(i, radarMargin, 1).x;            int y = getPoint(i, radarMargin, 1).y;         //   Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icons[i]);          //  int iconHeight = bitmap.getHeight();            int iconHeight = 20;            float titleWidth = titlePaint.measureText(titles[i]);            //底下两个角的坐标需要向下移动半个图片的位置(1、2)            if (i == 1) {                y += (iconHeight / 2);            } else if (i == 2) {                x -= titleWidth;                y += (iconHeight / 2);            } else if (i == 3) {                x -= titleWidth;            } else if (i == 4) {                x -= titleWidth / 2;            }            canvas.drawText(titles[i], x, y, titlePaint);        }    }    /**     * 绘制分数     *     * @param canvas 画布     */    private void drawScore(Canvas canvas) {        int score = 0;        //计算总分        for (int i = 0; i < dataCount; i++) {            score += data[i];        }        canvas.drawText(score + "", centerX, centerY + scoreSize / 2, scorePaint);    }    public int[] getColors(){        return colors;    }    public AbilityAnalysisView setColors(int[] colors){        this.colors = colors;        return this;    }    public String[] getTitles() {        return titles;    }    public AbilityAnalysisView setTitles(String[] titles) {        if (titles == null || titles.length < dataCount) {            throw new IllegalArgumentException("titles size can't be less than " + dataCount);        }        for (int i = 0; i < titles.length; i++) {            if (StringUtil.notEmpty(titles[i]).equals("N/A")) {                throw new IllegalArgumentException("value in titles can't be null or empty");            }        }        this.titles = titles;        return this;    }    public int getDataCount() {        return dataCount;    }    public AbilityAnalysisView setDataCount(int dataCount) {        if (dataCount < 3) {            throw new IllegalArgumentException("Edge of polygon can't be less than three");        }        dataCount = dataCount;        return this;    }    public float[] getDatas() {        return data;    }    public AbilityAnalysisView setDatas(float[] datas) {        if (datas == null || datas.length < dataCount) {            throw new IllegalArgumentException("datas size can't be less than " + dataCount);        }        this.data = datas;        return this;    }}

DensityUtils

/** * px与dp互相转换 * Created by yangle on 2016/4/12. */public class DensityUtils {    public static int dp2px(Context context, float dp) {        //获取设备密度        float density = context.getResources().getDisplayMetrics().density;        //4.3, 4.9, 加0.5是为了四舍五入        int px = (int) (dp * density + 0.5f);        return px;    }    public static float px2dp(Context context, int px) {        //获取设备密度        float density = context.getResources().getDisplayMetrics().density;        float dp = px / density;        return dp;    }}

StringUtill

/** * 空值判断 */public class StringUtil {    public static String notEmpty(String value) {        if (value != null && !TextUtils.isEmpty(value) && !TextUtils.isEmpty(value.trim())) {            return value;        }        return "N/A";    }}

更多相关文章

  1. Android绘制圆形图片(五)
  2. Android(安卓)surface 3 绘制 (的时机 java层)
  3. Android(安卓)NetworkLocationProvider and GeocodeProvider
  4. Android(安卓)百度地图 对鼠标点击、移动、抬起三个事件的监听
  5. android view相对于根布局的坐标获取
  6. android Draw Rect 坐标图示
  7. Android图形系统草稿
  8. Android(安卓)一个自定义View需要实现哪些方法
  9. Android之canvas详解

随机推荐

  1. SQL今日一题(4):表连接
  2. 5月小复盘
  3. 如何进行数据图形化?
  4. 2020年Python文章盘点,我选出了个人TOP10
  5. 如何做好描述统计分析
  6. SQL今日一题(5):一题多解
  7. 数据分析中会常犯哪些错误,如何解决?
  8. 数学之美:数学究竟是如何被运用到生活中的
  9. SQL今日一题(16):3表连接
  10. SQL今日一题(10)