Android开发中自定义饼图以及百分比展示

news2024/11/24 20:13:35

本篇文章主要讲解有关怎么用自定义View绘制圆形饼图,饼图内容包含:饼图内部添加百分比、绘制短延长线以及长延长线、延长线上添加文字说明。下面进行主要内容分析说明,文章最后附上全部代码以及具体使用说明:

效果图:

第一步:进行饼图的绘制:

        //绘制饼图
    private void drawPie(Canvas canvas) {
        //当前起始角度
        for (PieEntry1 pie : mPieLists) {
            mPaint.setColor(pie.getColor());//设置饼图的颜色
            canvas.drawArc(mRectF,
                    pie.getCurrentStartAngle(),
                    pie.getSweepAngle(),
                    true, mPaint);
        }
    }

第二步:绘制饼图内的百分比:

/**
     * 绘制各板块文字信息
     *主要绘制饼图中的百分比
     * @param canvas 画布
     */
    private void drawTextInner(Canvas canvas) {
        mTextPaint.setTextSize(blockTextSize);
        mTextPaint.setColor(blockTextColor);
        float currentDegree = startAngle;
        for (PieEntry1 pie : mPieLists) {
            canvas.save();
            //当前模块角平分线的sin和cos值
            float mathCos = (float) (Math.cos((pie.sweepAngle / 2 + currentDegree) / 180f * Math.PI));
            float mathSin = (float) (Math.sin((pie.sweepAngle / 2 + currentDegree) / 180f * Math.PI));
            String msg = pie.getLabel();
            Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
            float textRadius = mRadius / 2;

            if (disPlayPercent) {
                //获取文字高度,因水平已居中
                //设置文字格式
                String text = mFormat.format(pie.sweepAngle / 360f);
                //绘制模块百分比
                canvas.drawText(text, textRadius * mathCos,
                        textRadius * mathSin - metrics.ascent, mTextPaint);
            } else {
                //获取文字高度,因水平已居中
                float textHeight = metrics.descent - metrics.ascent;
                //绘制模块文字
                if (!TextUtils.isEmpty(msg)) {
                    canvas.drawText(msg, textRadius * mathCos,
                            textRadius * mathSin + textHeight / 2 - metrics.descent, mTextPaint);
                }
            }
            canvas.restore();
            currentDegree += pie.sweepAngle;
        }
    }

第三步:绘制圆环延长线以及线上面的说明:

 //延长线分为 延长点、线和文字说明三个部分
    private void drawLineAndText(Canvas canvas) {

        //算出延长线转折点相对起点的正余弦值
        double offsetRadians = Math.atan(yOffset / xOffset);
        float cosOffset = (float) Math.cos(offsetRadians);
        float sinOffset = (float) Math.sin(offsetRadians);

        for (PieEntry1 pie : mPieLists) {

            //延长点的位置处于扇形的中间
            float halfAngle = pie.getCurrentStartAngle() + pie.getSweepAngle() / 2;
            float cos = (float) Math.cos(Math.toRadians(halfAngle));
            float sin = (float) Math.sin(Math.toRadians(halfAngle));
            //通过正余弦算出延长点的位置
            float xCirclePoint = (mRadius + distance) * cos;
            float yCirclePoint = (mRadius + distance) * sin;

            mPaint.setColor(pie.getColor());

            //将饼图分为4个象限,从右上角开始顺时针,每90度分为一个象限
            int quadrant = (int) (halfAngle + 90) / 90;
            //初始化 延长线的起点、转折点、终点
            float xLineStartPoint = 0;
            float yLineStartPoint = 0;
            float xLineTurningPoint = 0;
            float yLineTurningPoint = 0;
            float xLineEndPoint = 0;
            float yLineEndPoint = 0;

            String text = pie.getLabel();
            String abovelabel = pie.getAbovelabel();

            //延长点、起点、转折点在同一条线上
            //不同象限转折的方向不同
            float cosLength = bigCircleRadius * cosOffset;
            float sinLength = bigCircleRadius * sinOffset;
            switch (quadrant) {
                case 0:
                    xLineStartPoint = xCirclePoint + cosLength;
                    yLineStartPoint = yCirclePoint - sinLength;
                    xLineTurningPoint = xLineStartPoint + xOffset;
                    yLineTurningPoint = yLineStartPoint - yOffset;
                    xLineEndPoint = xLineTurningPoint + extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.RIGHT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_F291C2));
                    canvas.drawCircle(xLineEndPoint-80, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setStyle(Paint.Style.FILL_AND_STROKE);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint-60, yLineEndPoint-10, mLinePaint);

                    break;
                case 1:
                    xLineStartPoint = xCirclePoint + cosLength;
                    yLineStartPoint = yCirclePoint + sinLength;
                    xLineTurningPoint = xLineStartPoint + xOffset;
                    yLineTurningPoint = yLineStartPoint + yOffset;
                    xLineEndPoint = xLineTurningPoint + extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.RIGHT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_FFCC66));
                    canvas.drawCircle(xLineEndPoint-110, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint-90, yLineEndPoint-10, mLinePaint);
                    break;
                case 2:
                    xLineStartPoint = xCirclePoint - cosLength;
                    yLineStartPoint = yCirclePoint + sinLength;
                    xLineTurningPoint = xLineStartPoint - xOffset;
                    yLineTurningPoint = yLineStartPoint + yOffset;
                    xLineEndPoint = xLineTurningPoint - extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.LEFT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_00CCCC));
                    canvas.drawCircle(xLineEndPoint-20, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint, yLineEndPoint-10, mLinePaint);
                    break;
                case 3:
                    xLineStartPoint = xCirclePoint - cosLength;
                    yLineStartPoint = yCirclePoint - sinLength;
                    xLineTurningPoint = xLineStartPoint - xOffset;
                    yLineTurningPoint = yLineStartPoint - yOffset;
                    xLineEndPoint = xLineTurningPoint - extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.LEFT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_4D88FF));
                    canvas.drawCircle(xLineEndPoint-20, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint, yLineEndPoint-10, mLinePaint);
                    break;
                default:
            }
            //绘制延长线
            canvas.drawLine(xLineStartPoint, yLineStartPoint, xLineTurningPoint, yLineTurningPoint, mLinePaint);
            canvas.drawLine(xLineTurningPoint, yLineTurningPoint, xLineEndPoint, yLineEndPoint, mLinePaint);
        }
    }

以上是绘制图形的主要代码,下面贴上整个自定义View的代码:

public class PieView extends View {
    private final int[] colors = {0xFFCCFF00, 0xFFCCFF00, 0xFFCCFF00, 0xFFCCFF00, 0xFFCCFF00, 0xFFCCFF00, 0xFFCCFF00,
            0xFFCCFF00, 0xFFCCFF00};
    //饼图初始绘制角度
    private float startAngle = -90;
    //延长点和饼图边缘的间距
    private float distance = 0F;

    //延长线转折点的横向偏移
    private float xOffset = 40F;
    //延长线转折点的纵向偏移
    private float yOffset = 24F;
    //延长线最长段部分的长度
    private float extend = 240F;
    private float circleRadius = 10F;


    private Paint mPaint;
    private Paint mlinetextPaint;
    private Paint mLinePaint;
    private Paint mcirclePaint;
    private RectF mRectF;


    /**
     * 文字画笔
     */
    private Paint mTextPaint;
    /**
     * 版块上的字号
     */
    public int blockTextSize = 20;
    /**
     * 版块上文字的颜色
     */
    public int blockTextColor = Color.WHITE;
    /**
     * decimal format
     */
    private final DecimalFormat mFormat = new DecimalFormat("#0.00%");
    /**
     * 是否展示百分比数
     */
    public boolean disPlayPercent = true;
    //View的可用总宽高
    private float mTotalWidth;
    private float mTotalHeight;
    //饼图+延长线+文字 所占用长方形总空间的长宽比
    private float mScale;
    //饼图的半径
    private float mRadius;

    private ArrayList<Integer> mColorLists;//饼图颜色
    private ArrayList<PieEntry1> mPieLists;
    private ArrayList<Integer> mColorCountLists;//饼图颜色
    private ArrayList<PieEntry1> mPieCountLists;
    private ArrayList<Integer> mCicleColorLists;//圆点颜色

    public PieView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //高度为WrapContent时,设置默认高度
        if (mScale != 0 && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            int height = (int) (mTotalWidth / mScale);
            setMeasuredDimension(widthMeasureSpec, height);
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //获取实际View的宽高
        mTotalWidth = w - getPaddingStart() - getPaddingEnd();
        mTotalHeight = h - getPaddingTop() - getPaddingBottom();
        //绘制饼图所处的正方形RectF
        initRectF();

    }

    //绘制饼图所处的正方形RectF
    private void initRectF() {

        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        //文字的高度
        float textHeight = fontMetrics.bottom - fontMetrics.top + fontMetrics.leading;
        //延长线的纵向长度
        float lineHeight = distance + bigCircleRadius + yOffset;
        //延长线的横向长度
        float lineWidth = distance + bigCircleRadius + xOffset + extend;
        //求出饼状图加延长线和文字 所有内容需要的长方形空间的长宽比
        mScale = mTotalWidth / (mTotalWidth + lineHeight * 2 + textHeight * 2 - lineWidth * 2);


        //长方形空间其短边的长度
        float shortSideLength;
        //通过宽高比选择短边
        if (mTotalWidth / mTotalHeight >= mScale) {
            shortSideLength = mTotalHeight;
        } else {
            shortSideLength = mTotalWidth / mScale;
        }
        //饼图所在的区域为正方形,处于长方形空间的中心
        //空间的高度减去上下两部分文字显示需要的高度,除以2即为饼图的半径
        mRadius = shortSideLength / 2 - lineHeight - textHeight;
        //设置RectF的坐标
        mRectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //将坐标中心设到View的中心
        canvas.translate(mTotalWidth / 2, mTotalHeight / 2);

        if (isPieListsNull()) {
            mPaint.setColor(Color.BLACK);
            canvas.drawText("请通过setData添加数据", -120, 0, mPaint);
        } else {
            //绘制饼状图
            drawPie(canvas);
            //绘制中心空洞
            drawHole(canvas);
            //绘制延长线和文字
            drawLineAndText(canvas);
            //绘制各板块文字信息
            drawTextInner(canvas);
        }

    }

    /**
     * 绘制各板块文字信息
     *主要绘制饼图中的百分比
     * @param canvas 画布
     */
    private void drawTextInner(Canvas canvas) {
        mTextPaint.setTextSize(blockTextSize);
        mTextPaint.setColor(blockTextColor);
        float currentDegree = startAngle;
        for (PieEntry1 pie : mPieLists) {
            canvas.save();
            //当前模块角平分线的sin和cos值
            float mathCos = (float) (Math.cos((pie.sweepAngle / 2 + currentDegree) / 180f * Math.PI));
            float mathSin = (float) (Math.sin((pie.sweepAngle / 2 + currentDegree) / 180f * Math.PI));
            String msg = pie.getLabel();
            Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
            float textRadius = mRadius / 2;

            if (disPlayPercent) {
                //获取文字高度,因水平已居中
                //设置文字格式
                String text = mFormat.format(pie.sweepAngle / 360f);
                //绘制模块百分比
                canvas.drawText(text, textRadius * mathCos,
                        textRadius * mathSin - metrics.ascent, mTextPaint);
            } else {
                //获取文字高度,因水平已居中
                float textHeight = metrics.descent - metrics.ascent;
                //绘制模块文字
                if (!TextUtils.isEmpty(msg)) {
                    canvas.drawText(msg, textRadius * mathCos,
                            textRadius * mathSin + textHeight / 2 - metrics.descent, mTextPaint);
                }
            }
            canvas.restore();
            currentDegree += pie.sweepAngle;
        }
    }

    //绘制饼图
    private void drawPie(Canvas canvas) {
        //当前起始角度
        for (PieEntry1 pie : mPieLists) {
            mPaint.setColor(pie.getColor());//设置饼图的颜色
            canvas.drawArc(mRectF,
                    pie.getCurrentStartAngle(),
                    pie.getSweepAngle(),
                    true, mPaint);
        }
    }

    //绘制中心空洞
    private void drawHole(Canvas canvas) {
        if (mShowHole) {
            mPaint.setColor(holeColor);
            canvas.drawCircle(0, 0, mRadius * holeRadiusProportion / 100, mPaint);
        }
    }

    //延长线分为 延长点、同心圆环和线三个部分
    private void drawLineAndText(Canvas canvas) {

        //算出延长线转折点相对起点的正余弦值
        double offsetRadians = Math.atan(yOffset / xOffset);
        float cosOffset = (float) Math.cos(offsetRadians);
        float sinOffset = (float) Math.sin(offsetRadians);

        for (PieEntry1 pie : mPieLists) {

            //延长点的位置处于扇形的中间
            float halfAngle = pie.getCurrentStartAngle() + pie.getSweepAngle() / 2;
            float cos = (float) Math.cos(Math.toRadians(halfAngle));
            float sin = (float) Math.sin(Math.toRadians(halfAngle));
            //通过正余弦算出延长点的位置
            float xCirclePoint = (mRadius + distance) * cos;
            float yCirclePoint = (mRadius + distance) * sin;
            mPaint.setColor(pie.getColor());
            //将饼图分为4个象限,从右上角开始顺时针,每90度分为一个象限
            int quadrant = (int) (halfAngle + 90) / 90;
            //初始化 延长线的起点、转折点、终点
            float xLineStartPoint = 0;
            float yLineStartPoint = 0;
            float xLineTurningPoint = 0;
            float yLineTurningPoint = 0;
            float xLineEndPoint = 0;
            float yLineEndPoint = 0;

            String text = pie.getLabel();
            String abovelabel = pie.getAbovelabel();

            //延长点、起点、转折点在同一条线上
            //不同象限转折的方向不同
            float cosLength = bigCircleRadius * cosOffset;
            float sinLength = bigCircleRadius * sinOffset;
            switch (quadrant) {
                case 0:
                    xLineStartPoint = xCirclePoint + cosLength;
                    yLineStartPoint = yCirclePoint - sinLength;
                    xLineTurningPoint = xLineStartPoint + xOffset;
                    yLineTurningPoint = yLineStartPoint - yOffset;
                    xLineEndPoint = xLineTurningPoint + extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.RIGHT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_F291C2));
                    canvas.drawCircle(xLineEndPoint-80, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setStyle(Paint.Style.FILL_AND_STROKE);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint-60, yLineEndPoint-10, mLinePaint);

                    break;
                case 1:
                    xLineStartPoint = xCirclePoint + cosLength;
                    yLineStartPoint = yCirclePoint + sinLength;
                    xLineTurningPoint = xLineStartPoint + xOffset;
                    yLineTurningPoint = yLineStartPoint + yOffset;
                    xLineEndPoint = xLineTurningPoint + extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.RIGHT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_FFCC66));
                    canvas.drawCircle(xLineEndPoint-110, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint-90, yLineEndPoint-10, mLinePaint);
                    break;
                case 2:
                    xLineStartPoint = xCirclePoint - cosLength;
                    yLineStartPoint = yCirclePoint + sinLength;
                    xLineTurningPoint = xLineStartPoint - xOffset;
                    yLineTurningPoint = yLineStartPoint + yOffset;
                    xLineEndPoint = xLineTurningPoint - extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.LEFT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_00CCCC));
                    canvas.drawCircle(xLineEndPoint-20, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint, yLineEndPoint-10, mLinePaint);
                    break;
                case 3:
                    xLineStartPoint = xCirclePoint - cosLength;
                    yLineStartPoint = yCirclePoint - sinLength;
                    xLineTurningPoint = xLineStartPoint - xOffset;
                    yLineTurningPoint = yLineStartPoint - yOffset;
                    xLineEndPoint = xLineTurningPoint - extend;
                    yLineEndPoint = yLineTurningPoint;
                    mlinetextPaint.setTextAlign(Paint.Align.LEFT);
                    mcirclePaint.setColor(getResources().getColor(R.color.color_4D88FF));
                    canvas.drawCircle(xLineEndPoint-20, yLineEndPoint - 60,circleRadius,mcirclePaint);
                    canvas.drawText(text, xLineEndPoint, yLineEndPoint - 50, mlinetextPaint);
                    mLinePaint.setTextSize(sp2px(12));
                    canvas.drawText(abovelabel, xLineEndPoint, yLineEndPoint-10, mLinePaint);
                    break;
                default:
            }
            //绘制延长线
            canvas.drawLine(xLineStartPoint, yLineStartPoint, xLineTurningPoint, yLineTurningPoint, mLinePaint);
            canvas.drawLine(xLineTurningPoint, yLineTurningPoint, xLineEndPoint, yLineEndPoint, mLinePaint);
        }
    }


    //初始化画笔
    private void initPaint() {
        //绘制饼图的画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.WHITE);
        mPaint.setTextSize(sp2px(12));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(1f);
        //绘制延长线的上面说明文字
        mlinetextPaint = new Paint();
        mlinetextPaint.setAntiAlias(true);
        mlinetextPaint.setColor(getResources().getColor(R.color.color_transparent));
        mlinetextPaint.setTextSize(sp2px(12));
        mlinetextPaint.setStyle(Paint.Style.FILL);
        mlinetextPaint.setStrokeWidth(1f);
        //绘制延长线的颜色
        mLinePaint = new Paint();
        mLinePaint.setAntiAlias(true);
        mLinePaint.setColor(getResources().getColor(R.color.color_9e));
        mLinePaint.setStyle(Paint.Style.FILL);
        mLinePaint.setStrokeWidth(2f);
        //绘制圆点
        mcirclePaint = new Paint();
        mcirclePaint.setColor(getResources().getColor(R.color.color_16CE12));
        mcirclePaint.setStyle(Paint.Style.FILL);
        mcirclePaint.setStrokeWidth(1f);

        //绘制中间百分比文字
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setFakeBoldText(true);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStrokeWidth(1f);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    //初始化数据
    private void initData() {
        if (isPieListsNull()) {
            return;
        }
        //当前起始角度
        float currentStartAngle = startAngle;
        for (int i = 0; i < mPieLists.size(); i++) {
            PieEntry1 pie = mPieLists.get(i);
            pie.setCurrentStartAngle(currentStartAngle);
            //每个数据百分比对应的角度
            float sweepAngle = pie.getPercentage() / 100 * 360;
            pie.setSweepAngle(sweepAngle);
            //起始角度不断增加
            currentStartAngle += sweepAngle;

            //未传入颜色时 以默认的颜色表作为颜色
            if (mColorLists == null || mColorLists.size() == 0) {
                int j = i % colors.length;
                pie.setColor(colors[j]);
            } else {
                pie.setColor(mColorLists.get(i));
            }
        }
    }
    //初始化数据
    private void initCountData() {
        if (isPieListsNull()) {
            return;
        }
        //当前起始角度
        float currentStartAngle = startAngle;
        for (int i = 0; i < mPieCountLists.size(); i++) {
            PieEntry1 pie = mPieCountLists.get(i);
            pie.setCurrentStartAngle(currentStartAngle);
            //每个数据百分比对应的角度
            float sweepAngle = pie.getPercentage() / 100 * 360;
            pie.setSweepAngle(sweepAngle);
            //起始角度不断增加
            currentStartAngle += sweepAngle;

            //未传入颜色时 以默认的颜色表作为颜色
            if (mColorCountLists == null || mColorCountLists.size() == 0) {
                int j = i % colors.length;
                pie.setColor(colors[j]);
            } else {
                pie.setColor(mColorCountLists.get(i));
            }
        }
    }
    //初始化颜色
    private void initColors() {
        if (isPieListsNull()) {
            return;
        }
        for (int i = 0; i < mPieLists.size(); i++) {
            mPieLists.get(i).setColor(mColorLists.get(i));
        }
    }

    //初始化颜色
    private void initCountColors() {
        if (isPieListsNull()) {
            return;
        }
        for (int i = 0; i < mPieCountLists.size(); i++) {
            mPieCountLists.get(i).setColor(mColorCountLists.get(i));
        }
    }

    //判断饼图颜色数据是否为空
    private boolean isPieListsNull() {
        return mPieLists == null || mPieLists.size() == 0;
    }

    //添加数据
    public void setData(ArrayList<PieEntry1> pieLists) {
        this.mPieLists = pieLists;
        initData();
        invalidate();
    }
    //添加数据
    public void setCountData(ArrayList<PieEntry1> mPieCountLists) {
        this.mPieCountLists = mPieCountLists;
        initCountData();
        invalidate();
    }

    //添加颜色
    public void setColors(ArrayList<Integer> colorLists) {
        this.mColorLists = colorLists;
        initColors();
        invalidate();
    }

    //添加颜色
    public void setCountColors(ArrayList<Integer> mColorCountLists) {
        this.mColorCountLists = mColorCountLists;
        initCountColors();
        invalidate();
    }


    /**
     * Value of sp to value of px.
     *
     * @param spValue The value of sp.
     * @return value of px
     */
    public static int sp2px(final float spValue) {
        final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    public static class PieEntry1 {
        //颜色
        private int color;
        private int circleColor;
        //比分比
        private float percentage;
        //条目名
        private String label;
        private String abovelabel;
        //扇区起始角度
        private float currentStartAngle;
        //扇区总角度
        private float sweepAngle;

        public String getAbovelabel() {
            return abovelabel;
        }

        public void setAbovelabel(String abovelabel) {
            this.abovelabel = abovelabel;
        }

        public int getCircleColor() {
            return circleColor;
        }

        public void setCircleColor(int circleColor) {
            this.circleColor = circleColor;
        }

        public PieEntry1(float percentage, String label, String abovelabel) {
            this.percentage = percentage;
            this.label = label;
            this.abovelabel = abovelabel;
        }

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
        }

        public float getPercentage() {
            return percentage;
        }

        public void setPercentage(float percentage) {
            this.percentage = percentage;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public float getSweepAngle() {
            return sweepAngle;
        }

        public void setSweepAngle(float sweepAngle) {
            this.sweepAngle = sweepAngle;
        }

        public float getCurrentStartAngle() {
            return currentStartAngle;
        }

        public void setCurrentStartAngle(float currentStartAngle) {
            this.currentStartAngle = currentStartAngle;
        }
    }
}

第四步:具体的使用说明:

在xml中添加自定义的View,例如:

<com.dz.common.view.PieView
    android:id="@+id/pieview"
    android:layout_width="match_parent"
    android:layout_height="300dp" />

在activity的初始化中使用:

pieview.setColors(createsleepColors()
pieview.setData(createsleepData())
//设置数据
private fun createsleepData(): ArrayList<PieView.PieEntry1>? {
    val pieLists: ArrayList<PieView.PieEntry1> = ArrayList()
    pieLists.add(PieView.PieEntry1(20.00f, "觉醒", "0时45分"))
    pieLists.add(PieView.PieEntry1(30.00f, "浅睡眠", "8时45分"))
    pieLists.add(PieView.PieEntry1(30.00f, "深睡眠", "3时45分"))
    pieLists.add(PieView.PieEntry1(20.00f, "REM分期", "10时45分"))
    return pieLists
}
//设置对应数据所需的颜色
private fun createsleepColors(): ArrayList<Int>? {
    val colorLists: ArrayList<Int> = ArrayList()
    colorLists.add(Color.parseColor("#F291C2"))//粉色
    colorLists.add(Color.parseColor("#FFCC66"))//黄色
    colorLists.add(Color.parseColor("#00CCCC"))//浅绿
    colorLists.add(Color.parseColor("#4D88FF"))//深蓝
    return colorLists
}

以上就是自定义饼图的全部内容,如需转载请附上原创的链接,谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1186957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3d max软件中的缓存垃圾该如何清理?

使用3d max建模到渲染操作&#xff0c;来回对效果图调整的次数过多时&#xff0c;就会出现一下看不到的垃圾缓存&#xff0c;影响保存的速度&#xff0c;影响效率&#xff01; 对于这类的3d垃圾清理的有什么高效方法呢&#xff1f; 3dmax垃圾清理的常规操作如下&#xff1a; 1、…

pandas的一些函数

1、pd.read_csv () 读取csv文件 import pandas as pddf pd.read_csv(Popular_Baby_Names.csv)df pd.read_csv(Popular_Baby_Names.csv, sep;, header0, index_col0, skiprows5, na_valuesN/A)##读取CSV文件data.csv&#xff0c;使用;作为分隔符&#xff0c;第一行作为标题&…

idea 一直卡在maven正在解析maven依赖

修改maven Importing的jvm参数 -Xms1024m -Xmx2048m

OpenAI开发者大会之后,当何去何从?

简介 过往总结 ​产品升级 GPT-4 Turbo Agent化 此间的未来 定制GPT GPT商店 Assistants API 总结与思考 简介 此次发布会简单总结如下。 1. 发布GPT-4 Turbo&#xff1a; 更长。支持128K上下文输入&#xff0c;标准GPT-4是8K版本&#xff0c;之前升级出了32K版本 更…

kubernetes (k8s)的使用

一、kubernetes 简介 谷歌2014年开源的管理工具项目&#xff0c;简化微服务的开发和部署。 提供功能&#xff1a;自愈和自动伸缩、调度和发布、调用链监控、配置管理、Metrics监控、日志监控、弹性和容错、API管理、服务安全等。官网&#xff1a;https://kubernetes.io/zh-cn…

5-爬虫-打码平台、打码平台自动登录打码平台、selenium爬取京东商品信息、scrapy介绍安装、scrapy目录结构

1 打码平台 1.1 案例 2 打码平台自动登录打码平台 3 selenium爬取京东商品信息 4 scrapy介绍安装 5 scrapy目录结构 1 打码平台 # 1 登录某些网站&#xff0c;会有验证码---》想自动破解-数字字母&#xff1a;python模块&#xff1a;ddddocr-计算题&#xff0c;成语题&#xf…

物联网AI MicroPython学习之语法 ucollections集合和容器类型

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; ucollections 介绍 ucollections 模块用于创建一个新的容器类型&#xff0c;用于保存各种对象。 接口说明 namedtuple - 创建一个新namedtuple容器类型 函数原型&#xff1a; 创建一个具有特定名称和一组…

rviz添加qt插件

一、增加rviz plugin插件 资料&#xff1a;http://admin.guyuehome.com/42336 https://blog.51cto.com/u_13625033/6126970 这部分代码只是将上面两个链接中的代码整合在了一起&#xff0c;整合在一起后可以更好的理解其中的关系 1、创建软件包 catkin_create_pkg rviz_tel…

MySQL数据库的各种锁介绍以及它们之间的关系

MySQL数据库的各种锁 表级锁、行级锁、间隙锁、意向锁、记录锁&#xff0c;悲观锁和乐观锁 表级锁包含表级共享锁和表级排他锁行级锁包含行级共享锁和行级排他锁间隙锁是行级锁的一种特殊锁&#xff0c;锁定既定列的范围值意向锁是事务对表中某些行或者范围发起的一项操作&am…

Hbuiderx链接到夜神模拟器(DCloud数字天堂)

赞助 DCloud 即数字天堂&#xff08;北京&#xff09;网络技术有限公司是 W3C成员及 HTML5中国产业联盟 发起单位 Hbuiderx切换使用夜神模拟器自带的ADB.exe链接到夜神模拟器 同步资源失败&#xff0c;未得到同步资源的授权&#xff0c;请停止运行后重新运行&#xff0c;并注意…

数据的读取和保存-MATLAB

1 序言 在进行数据处理时&#xff0c;经常需要写代码对保存在文件中的数据进行读取→处理→保存的操作&#xff0c;流程图如下&#xff1a; 笔者每次在进行上述操作时&#xff0c;都需要百度如何“选中目标文件”以及如何“将处理好的数据保存到目标文件中”&#xff0c;对这一…

本地域名 127.0.0.1 / localhost

所谓本地域名就是 只能在本机使用的域名 &#xff0c;一般在开发阶段使用。 编辑文件 C:\Windows\System32\drivers\etc\hosts。 127.0.0.1 www.baidu.com如果修改失败,可以修改该文件的权限。 原理&#xff1a; 在地址栏输入 域名 之后&#xff0c;浏览器会先进行 DNS…

SpringBoot定时任务打成jar 引入到新的项目中后并自动执行

一、springBoot开发定时任务 ①&#xff1a;连接数据库实现新增功能 1. 引入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional> </dependency> <dependen…

Python高级语法----深入理解Python协程

文章目录 什么是协程?Python中的协程基本示例协程和事件循环总结Python协程是一种非常强大的并发编程概念,让你能够高效地处理多任务。协程在Python中的使用已经变得越来越流行,特别是在异步编程中。本文将用通俗易懂的语言来介绍协程的概念,并提供实际的代码示例和执行结果…

软件测试怎么测别的类的main方法

软件测试怎么测别的类的main方法 🍎如果软测开发者题目待测类里有main方法,我们如何测? 可以采取以下步骤: 了解main函数的功能:首先,你需要了解这个main函数的功能和预期的输出。这样你才能设计出合适的测试用例。设计测试用例:设计测试用例时,需要考虑各种可能的输…

【Linux】了解文件的inode元信息,以及日志分析

目录 一、inode表结构&#xff0c;以及元信息 1、了解inode信息有哪些 2、关于inode表的说明 Linux中访问文件的过程&#xff1a; 3、硬连接与软连接的区别&#xff0c;&#xff08;请看前面&#xff0c;写过的&#xff09; 二、文件系统的备份与恢复 三、几种常见的日志…

【uniapp】签名组件,兼容vue2vue3

网上找了个源码改吧改吧&#xff0c;清除了没用的功能和兼容性&#xff0c;基于uniapp开发的 样子 vue2 使用方法&#xff0c;具体的可以根据业务自行修改 <signature ref"signature" width"100%" height"410rpx"></signature>confi…

C函数的反汇编

fromelf --bin --outputxxx.bin xxx.axf fromelf --text -a -c --outputxxx.dis xxx.axf去Linker下面复制该目录下的xxx.axf xxx.dis名字随便改&#xff0c;保证后缀是dis就行 然后确认&#xff0c;进行编译 就生成了task.dis文件

【MySQL】库操作和表操作

文章目录 一、库操作1. 创建数据库2. 数据库的编码问题查看系统默认支持的字符集查看数据库支持的字符集查看数据库支持的字符集校验规则校验规则对数据库的影响 3. 操纵数据库查看数据库显示创建语句修改数据库删除数据库 4. 数据库的备份和恢复数据库的备份数据库的恢复表的删…

从业务到软件架构——软件建模

一、问题 1.架构到底是什么&#xff1f;架构和业务之间到底什么关系&#xff1f; 2.好的架构的设计出发点是什么&#xff1f;好的架构应该是什么样的&#xff1f; 作为一个计算机领域的词汇&#xff0c;架构的定义是&#xff1a;有关软件整体结构与组件的抽象描述&#xff0c…