Android自定义View饼状图的绘制总结

Android自定义View饼状图的绘制总结

        之前简单介绍了绘制折线图,博客:
http://blog.csdn.net/wenzhi20102321/article/details/64923994

        这里介绍一下饼状图,饼状图的绘制相对来说还是更简单一点的。
效果,如图:
z
输入任意一组的分数值,并设置一组颜色,就可以实现上面的效果。

一.需要的自定义View的基础知识

(一)编写自定义MyView类

1.这个MyView需要继承View。不用解释吧。

2.需要重写两个方法,onSizeChange和onDraw方法,这里是不需要重写onMeasure方法的,因为这个自定义View的视图大小没有发生改变,但是如果需要也是可以重写的。

执行顺序:onMeasure-》onSizeChange—》onDraw

自定义的View中三个最重要的方法解释:

onMeasure可以得到并控制本身和子View的大小
onSizeChange可以得到自身视图View的大小
onDraw绘制视图View的具体实现

(二)绘制的方法API

1.绘制弧形

canvas.drawArc(oval, starDegree, endDegree, true, mPaint);
说明:第一个参数代表的是弧形显示的矩形面积。
第二个参数代表开始的角度数,
第三个参数代表结束的角度数,
第四个参数代表是否显示实心,
第五个参数设计画笔对象。

2.绘制文字

canvas.drawText(“心跳的频率”, x, y, mPaint);
说明:第一个参数是要绘制的文字,第二三个参数代表文字绘制开始的左边,第四个参数代表画笔对象。

(三)本文折线的思路分析:

使用的方法主要是canvas.drawArc来绘制连续的扇形。

1.要算出每个范围占有的个数

2.算出每个范围占有360角度中的度数

3.下一个扇形开始的角度是上一个扇形开始的角度数加上他图形的角度数。

二.扇形设计实例

(一)自定义View类PieCharView

package com.example.charview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * 饼状图
 */


public class PieCharView extends View {
    private int mWidth;
    private int mHeight;
    private String[] pieName;
    private RectF oval;
    private String[] rangeString;
    private List<Integer> listRange = new ArrayList<Integer>();
    private List<Integer> listNunber = new ArrayList<Integer>();
    private int[] paintColors;
    private List<Float> listDegree = new ArrayList<Float>();
    private Paint mPaint;

    public PieCharView(Context context) {
        this(context, null);
    }

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

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

    /**
     * @param listNunber  数的集合
     * @param paintColors 画笔颜色集合
     * @param pieName     饼状图的名称
     */
    public void setData(List<Integer> listNunber, int[] paintColors, String[] pieName, String[] rangeString) {
        this.rangeString = rangeString;
        this.pieName = pieName;
        this.listNunber.clear();
        this.listNunber.addAll(listNunber);
        this.paintColors = paintColors;
        initDegree();//计算数量占有的度数(比例)
        postInvalidate();
    }

    private void initDegree() {
        //遍历集合的数据  ,并判断范围
        int num_60 = 0;
        int num60_80 = 0;
        int num80_ = 0;
        for (int number : listNunber) {
            if (number < 60) {
                num_60++;
            } else if (number < 80) {
                num60_80++;
            } else {
                num80_++;
            }
        }
        //比例的个数添加到集合中
        listRange.add(num_60);
        listRange.add(num60_80);
        listRange.add(num80_);

        //计算比例并添加到集合中
        listDegree.add(360f * num_60 / listNunber.size());
        listDegree.add(360f * num60_80 / listNunber.size());
        listDegree.add(360f * num80_ / listNunber.size());

    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStrokeWidth(2f);
        mPaint.setColor(Color.WHITE);
        setBackgroundColor(Color.BLACK);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制背景颜色和背景线
        drawBackGroudLines(canvas);

        //画饼状图和文字
        drawArcView(canvas);


    }

    private void drawArcView(Canvas canvas) {
        float starDegree = -10;   //开始的角度是可以任意的
        mPaint.setTextSize(30);
        //画饼状图
        for (int i = 0; i < listDegree.size(); i++) {
            mPaint.setColor(paintColors[i]); //设置线条的颜色,Int类型
            Log.e("TAG", "listDegree:" + listDegree.get(i));
            canvas.drawArc(oval, starDegree, listDegree.get(i), true, mPaint);
            starDegree += listDegree.get(i);

            //画文字
            canvas.drawText(pieName[i] + "(" + rangeString[i] + "):" + listRange.get(i) + "次", 10, 450 + i * 50, mPaint);

        }
    }


    private void drawBackGroudLines(Canvas canvas) {
        //背景颜色,灰色
        mPaint.setColor(0x80CCCCCC);
        canvas.drawRect(0, 0, mWidth, mHeight, mPaint);
        canvas.drawLine(0, 0, mWidth, 0, mPaint);
        canvas.drawLine(0, mHeight, mWidth, mHeight, mPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getWidth();
        mHeight = getHeight();
        oval = new RectF((mWidth - 400) / 2, 10, (mWidth - 400) / 2 + 400, 410);

    }

}

(二)主方法类调用自定义View

package com.example.charview;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class MyActivity extends Activity {


    /**
     * 自定义折线图的实现
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
           setContentView(R.layout.main);
        //数据
        List<Integer> datas = new ArrayList<Integer>();
        datas.add(66);
        datas.add(77);
        datas.add(66);
        datas.add(100);
        datas.add(64);
        datas.add(20);
        datas.add(44);
        datas.add(22);
        datas.add(99);
        datas.add(35);
        datas.add(35);
        datas.add(66);
        datas.add(6);
        datas.add(20);


        // 画笔颜色的数组
        int[] paintColor = {Color.RED, Color.YELLOW, Color.BLUE};
        //饼状图的文字描述
        String[] pieString = {"不及格", "良好", "优秀"};
        //设置的范围描述
        String[] pieRangeString = {"<60", "60-80", ">80"};

        PieCharView pieCharView = (PieCharView) findViewById(R.id.pieCharView);

        pieCharView.setData(datas, paintColor, pieString, pieRangeString);

    }


    //关闭页面
    public void close(View view) {
        finish();
    }
}

(三)布局文件是非常简单的

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >

    <com.example.charview.PieCharView
            android:layout_width="match_parent"
            android:layout_height="400dp"
            android:id="@+id/pieCharView"
            />
    <Button
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="关闭"
            android:onClick="close"
            />

</LinearLayout>

        这里的扇形统计图算是很简单的了,使用的方法也是比较简单的,对于初级学习是很有帮助的。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值