Android PieChart 饼图控件

本文介绍如何在Android中自定义饼图View,以满足特定UI设计需求。通过文章,读者将了解使用预览、代码分析以及自定义饼图的源码详细过程。
摘要由CSDN通过智能技术生成

今天写一个饼图自定义View的文章。由于公司的项目需要用到饼图,UI给的设计图和自己找的一个饼图框架的标题位置不符,所以就自己画了一个。

1,使用预览

PieChart mChart mChart = (PieChart) findViewById(R.id.pieChar);
mChart = (PieChart) findViewById(R.id.pieChar);
String[] titles = new String[] {"钱包余额","金钱袋资产","金宝箱资产"};
mChart.setTitles(titles);
int[] colors = new int[]{0xfff5a002,0xfffb5a2f,0xff36bc99};
mChart.setColors(colors);
mChart.setValues(new double[]{999,999,999});
mChart.postInvalidate();
需要传入标题和值,每个饼的颜色也可以重新设置,不传颜色值就用默认的。画饼图的难点就在数学计算和逻辑思维能力。
 

2代码分析

/**
	 * 获得每个值所占的角度
	 * @return
	 */
	private float[] getAngles(){
		if(mValues == null || mValues.length == 0) return null;
		double sum = 0;
		int len = mTitles.length;
		float[] angles = new float[len];
		int gapCount = 0;//饼图间隙条数
		for(int i=0;i<len;i++){
			sum += mValues[i];
			if(mValues[i]>0)
				gapCount++;
		}
		float angle = 0;
		pieAngle = 360 - gapCount*ANGLE_DIS;
		for(int i=0;i<len-1;i++){
			angles[i] = (float)(pieAngle*mValues[i]/sum);
			angle += angles[i];
		}
		if(mValues[len-1]>0)
			angles[len - 1] = pieAngle - angle;
		
		return angles;
 	}
根据传过来的值计算每个值所占的角度,饼图之间有1°的间隙,
if(mValues[i]>0) gapCount++;只有值大于0时才画饼,才增加一条间隙。
pieAngle = 360 - gapCount*ANGLE_DIS;这里计算所有饼所占整个圆的角度。
if(mValues[len-1]>0) angles[len - 1] = pieAngle - angle;最后一个饼的角度为饼的总角度减去前面所有饼的角度之和,这样做是为了让所有饼的角度加起来等于pieAngle这个角度,减少除法运算的小数误差效果。
 
	/**
	 * 在饼图的每个饼上写上百分比,必须放在计算了每个值所占的角度angles之后
	 * @param canvas
	 */
	private void setPieContentText(Canvas canvas){
		float pre = 0;
		float[] centerAngle = new float[mAngles.length];
		for(int i=0;i<mAngles.length;i++){
			if(mAngles[i] == 0) continue;
			centerAngle[i] = ANGLE_DIS+mAngles[i]/2 + pre;
			pre += mAngles[i];
		}
		float cenR = pieR*1.0f/2*3/5;
		float lastPir = 1.0f;//为了使所有的%比加起来等于1
		mTextPaint.setColor(0xFFFFFFFF);
		float cenX = 0;
		float cenY = 0;
		for(int i=0;i<centerAngle.length;i++){
			if(centerAngle[i]==0 ) continue;
			float xa = (float) (cenR * Math.cos(centerAngle[i] * (Math.PI / 180)));
			float ya = (float) (cenR * Math.sin(centerAngle[i] * (Math.PI / 180)));
			cenX = getWidth()*1.0f/2+xa;
			cenY = TOP_PADDING + pieR*1.0f/2 + ya;
			mTextPaint.setTextSize(mPieTextSize);
			double curPer = numDecimals(mAngles[i]/pieAngle);
			String perMsg = i==centerAngle.length-1?percentFormat(lastPir):p
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值