Android自定义View之扇形饼状图

本文介绍如何在Android中自定义一个扇形饼状图View,详细讲解了构造方法、onMeasure()、onDraw()的实现,包括扇形绘制、动画效果、文字添加和立体感的创建。同时还探讨了代码的优化,如dp/sp/px转换、动画控制和数据设置。
摘要由CSDN通过智能技术生成

前言:继上次写了自定义圆形进度条后,今天给大家带来自定义扇形饼状图。先上效果图:
水果大拼盘
是不是很炫?看上去还有点立体感。下面带大家一起来瞧一瞧吧。

一、定义成员变量,重写构造方法

看着这个效果图,我们可以想象下接下来暂时会需要用到以下属性:

    /**
     * 存放事物的品种与其对应的数量
     */
    private Map kindsMap = new LinkedHashMap<String, Integer>();
    /**
     *  存放颜色
     */
    private ArrayList<Integer> colors = new ArrayList<>();

    private Paint mPaint;//饼状画笔
    private Paint mTextPaint; // 文字画笔
    private static final int DEFAULT_RADIUS = 200;
    private int mRadius = DEFAULT_RADIUS; //外圆的半径
    private String centerTitle; //中间标题

然后重写父类的构造方法,初始化画笔:

 public PieChatView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mTextPaint = new Paint();

        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);

        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.STROKE);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    public PieChatView(Context context) {
        this(context, null, 0);

    }

    public PieChatView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

一般都是一个参数和两个参数的全部调用第三个参数的。我三个参数的构造方法中没有去从xml文件中去获取属性了。我完全就用代码实现了。也可以将一些属性放在attrs.xml文件中,然后去获取。自行选择吧。

二、onMeasure()

这个方法,只要你以前写过自定义View,基本上就是一样的套路:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wideSize = MeasureSpec.getSize(widthMeasureSpec);
        int wideMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width, height;
        if (wideMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
            width = wideSize;
        } else {
            width = mRadius * 2 + getPaddingLeft() + getPaddingRight();
            if (wideMode == MeasureSpec.AT_MOST) {
                width = Math.min(width, wideSize);
            }

        }

        if (heightMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
            height = heightSize;
        } else {
            height = mRadius * 2 + getPaddingTop() + getPaddingBottom();
            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(height, heightSize);
            }

        }
        setMeasuredDimension(width, height);
        mRadius = (int) (Math.min(width - getPaddingLeft() - getPaddingRight(),
                height - getPaddingTop() - getPaddingBottom()) * 1.0f / 2);

    }

就是获得系统测量好的宽高,和模式后分三种模式去讨论。最终通过setMeasuredimension()确定宽高的值。宽高确定好了,那就可以确定下整个饼状图的半径 mRadius了。取宽高中的较小的那个。

三、onDraw();

我们需要画一个一个的扇形,还有将扇形从零到360的动画效果,还有扇形中的文字,中间的文字,还有实现立体感的效果。

1.画扇形。

画一个扇形还是蛮容易的:通过画布调用drawArc()方法话一个60度的扇形:
mPaint.setStyle(Paint.Style.FILL);
mTextPaint.setColor(Co
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值