自定义View,仿蚂蚁芝麻分分析图(早前的一版)

博客提供了芝麻信用分仪表盘图的代码及使用说明,还给出了相关博客链接https://blog.csdn.net/wxx_csdn/article/details/90714466 ,涉及自定义view相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码

package com.xinxin.applicationtest.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import com.xinxin.applicationtest.R;

/**
 * Created by wxx on 2016/11/22  0022.
 * 作用 : 仿支付宝芝麻信用分 评分视图
 */

public class CreditView extends View {
    //数据个数
    private int dataCount = 5;
    //每个角的弧度
    private float radian = (float) (Math.PI*2/dataCount);
    //中间雷达图半径
    private float radius;
    //各个维度的分值
    private float[] data = {160,150,120,130,190};
    //最大分值
    private float maxValue = 190;
    //中心坐标
    private int centerX;
    private int centerY;
    //标题
    private String[] titles = {"人际关系","够不够NB","够不够屌","后台硬不硬","有没有钱"};
    //图标
    private int[] icons = {R.drawable.ic_android_black_24dp,R.drawable.ic_autorenew_black_24dp,
            R.drawable.ic_wrap_text_black_24dp,R.drawable.ic_format_shapes_black_24dp,R.drawable.ic_directions_car_black_24dp};
    //中间分数大小,dip 值
    private int scoreSize = 33;
    //标题文字大小,dip 值
    private int titleSize = 22;
    //雷达区边界线的画笔
    private Paint mainPaint;
    //雷达区填充区域的画笔
    private Paint valuePaint;
    //中间总分的画笔
    private Paint scorePaint;
    //标题的画笔
    private Paint titlePaint;
    //标题的边距
    private int radarMargin = 20;


    public CreditView(Context context) {
        super(context);
        initPaint();
    }

    public CreditView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public CreditView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    private void initPaint(){
        mainPaint = new Paint();
        mainPaint.setAntiAlias(true);
        mainPaint.setColor(Color.WHITE);
        mainPaint.setStyle(Paint.Style.STROKE);
        mainPaint.setTextSize(0.1f);

        valuePaint = new Paint();
        valuePaint.setAntiAlias(true);
        valuePaint.setColor(Color.BLUE);
        valuePaint.setAlpha(50);

        scorePaint = new Paint();
        scorePaint.setColor(Color.WHITE);
        scorePaint.setTextSize(scoreSize);

        titlePaint = new Paint();
        titlePaint.setColor(Color.WHITE);
        titlePaint.setTextSize(titleSize);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        radius = Math.min(w,h)/2*0.5f;
        centerX = w/2;
        centerY = h/2;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawPolygon(canvas);
        drawLine(canvas);
        drawRegion(canvas);
        drawScore(canvas);
        drawTitle(canvas);
        drawIcon(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);
    }

    /**
     * 画雷达区中间的线
     * @param canvas
     */
    private void drawLine(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 canvas
     */
    private void drawRegion(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.FILL_AND_STROKE);
        canvas.drawPath(path, valuePaint);
    }

    /**
     * 绘制中间的总分
     * @param canvas
     */
    private void drawScore(Canvas canvas) {
        int score =0;
        for (int i = 0; i < dataCount; i++) {
            score += data[i];
        }

        //测量文本的宽高
        Rect bounds = new Rect();
        scorePaint.getTextBounds(String.valueOf(score),0,String.valueOf(score).length(),bounds);
        int width = bounds.width();
        int height = bounds.height();

        canvas.drawText(String.valueOf(score),centerX - width/2,centerY + height/2,scorePaint);
    }

    /**
     * 画五个标题
     * @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;
            
            //测量文本的宽高
            Rect bounds = new Rect();
            titlePaint.getTextBounds(titles[i],0,titles[i].length(),bounds);
            int width = bounds.width();
            int height = bounds.height();
            if(i == 1) {
                y += height;
            }else if(i == 2) {
                x -= width;
                y += height;
            }else if(i == 3) {
                x -= width;
            }else if(i == 4) {
                x -= width/2;
            }
            canvas.drawText(titles[i],x,y,titlePaint);
        }
    }

    /**
     * 画五个图标
     * @param canvas
     */
    private void drawIcon(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]);
            //测量文本的宽高
            Rect bounds = new Rect();
            titlePaint.getTextBounds(titles[i],0,titles[i].length(),bounds);
            int width = bounds.width();
            int height = bounds.height();
            if(i == 0) {
                x += width/2 - bitmap.getWidth()/2;
                y -= height + bitmap.getHeight();
            }else if(i == 1) {
                x += width/2 - bitmap.getWidth()/2;
                y -= bitmap.getHeight();
            }else if(i == 2) {
                x -= width/2 + bitmap.getWidth()/2;
                y -= bitmap.getHeight();
            }else if(i == 3) {
                x -= width/2 + bitmap.getWidth()/2;
                y -= height + bitmap.getHeight();
            }else if(i ==4) {
                x -= bitmap.getWidth()/2;
                y -= height + bitmap.getHeight();
            }
            canvas.drawBitmap(bitmap,x,y,titlePaint);
        }
    }

    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);
    }

    public void setData(float[] data) {
        this.data = data;
        postInvalidate();
    }
}

使用

view.setData({160,150,120,130,190});

还有一个芝麻信用分仪表盘图的 点击查看 https://blog.csdn.net/wxx_csdn/article/details/90714466

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值