自定义View02 Android饼状图
网上有很多很炫酷的自定义控件,我们也非常乐意将这些新奇技术在项目中使用。但是对于刚刚参加工作或者初学者来说!多数都是只可远观,因为内容过于复杂根本无法理解具体的含义,更别提应用了,本文会讲解一个非常简单的自定义饼状图控件,先从最简单的开始学起!
自定义控件大致分类
1.继承原有控件!继承原有控件功能!扩展新功能!
例如:创建一个类继承EditText(可以看本博客自定义控件01),增加在每行文本下划线功能。
2.继承ViewGroup或者其子类!利用视图容器特点,实现控件组合功能!
例如:a-z指示器 ,瀑布流或者流式布局等。
3.继承View,实现完全绘制!
例如: 弹幕,K线图等等本文就继承View实现完全自己绘制功能!
饼状图控件设计思路
用户给定数据(可以是数组/集合),根据用户提供的数据,绘制饼状图!
直接上代码!看注释
/**
* User: zwf(348088053@qq.com)
* Date: 2016/08/24
* Time: 16:21
* progject: Android_Day28_View03
* Describe:饼状图控件
*/
public class Piechart extends View {
private float [] result ; //用户提供的数据
private Paint paint; //画图的笔
private Random random; //随机数
private RectF rectF; //绘制Arc弧形需要的 外边矩形
//Java代码实例控件调用
public Piechart(Context context) {
super(context);
init(context,null);
}
//Xml布局中实例化对象调用
//attrs xml中 控件生名属性的集合
public Piechart(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
/**
* onDraw()方法中可能经常刷新调用!避免在onDraw方法中进行对象实例工作!
* 所在定义了一个init初始化数据方法!确保在Java和Xml布局中创建控件都会调用
* 所以在两个构造方法中都进行了调用!
*/
private void init(Context context, AttributeSet attrs) {
paint = new Paint();
paint.setAntiAlias(true); //抗锯齿
rectF = new RectF();
random = new Random();
}
/**
* 预留方法,控件对象调用,用于传递数据!传递数据后进行刷新
*/
public void setData(float [] result){
this.result = result;
//赋值以后刷新ondraw()
String name = Thread.currentThread().getName();
if (name.equals("main")){
invalidate(); //主线程中需要调用invalidate()刷新,也就是再次调用onDraw()方法!
}else{
postInvalidate(); //子线程中需要调用postInvalidate()刷新!
}
}
@Override
protected void onDraw(Canvas canvas) {
if (result != null && result.length>0) {
//数据总值(用于后期计算每个数据对应的角度)
float count = 0;
//计算总值
for (float v : result) {
count+=v;
}
//当前控件的宽和高
int height = getHeight();
int width = getWidth();
//取一个较小的值
int distance = Math.min(height,width); //取小值
//饼状图的外边矩形
//注意:圆形饼状图,要求外边矩形是正方型!
rectF.top = 0;
rectF.left =0;
rectF.right=distance;
rectF.bottom= distance;
//起始角度 默认起始角度是0,随机提高美观性!
float startAngle = random.nextFloat()*180;
for (int i = 0; i < result.length; i++) {
//循环绘制每个饼
float swap = (360/count)*result[i]; //经过的角度
//画笔的颜色 随机
int color = Color.rgb(random.nextInt(256),random.nextInt(256),random.nextInt(256));
paint.setColor(color);
canvas.drawArc(rectF,startAngle,swap,true,paint);
startAngle += swap; //当前的经过的角度累计,下一个饼起始的角度
}
}
}
}
XML中使用
<!--自定义控件 v4 v7等第三方包控件,要写全名称 -->
<com.qianfeng.android_day28_view03.widget.piechart
android:id="@+id/pie"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity中使用
Piechart piechart = (Piechart) findViewById(R.id.pie);
float [] data = new float[]{8,9,10,11,12}; //模拟数据
piechart.setData(data); //设置数据即可
效果图
需要掌握
自定义控件,不会自动刷新(调用onDraw()方法),如果需要根据给定数据绘制,还需要手动调用刷新方法
main主线程中:invalidate()刷新
work子线程中:postInvalidate()刷新