您的位置:首页 > 移动开发 > Android开发

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

2017-03-27 11:50 274 查看

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

之前简单介绍了绘制折线图,博客:

http://blog.csdn.net/wenzhi20102321/article/details/64923994

这里介绍一下饼状图,饼状图的绘制相对来说还是更简单一点的。

效果,如图:



输入任意一组的分数值,并设置一组颜色,就可以实现上面的效果。

一.需要的自定义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>


这里的扇形统计图算是很简单的了,使用的方法也是比较简单的,对于初级学习是很有帮助的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: