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

Android 超强动态环信比列图 (自定义View)

2015-11-18 17:39 393 查看
这篇博客主要是介绍通过自定义view实现一个动态环信比列图

博客只介绍核心代码,博客最后会给一个源码下载地址

话不多说直接上代码,代码是最好的老师(卧槽,说的我自己都被自己征服了)

小小提醒一下,如果对自定义view不是很熟悉的小伙伴,建议去看鸿洋大神自定义view系列博客

哎,好人做到底,鸿洋大神博客地址 鸿洋大婶子-自定义

这回真的上干货了

首先是自定义属性的文件在attrs.xml文件中定义

<declare-styleable name="RingView">
<!--环形比例图的尺寸-->
<attr name="ringSize" format="dimension" />
<!--环形的宽度-->
<attr name="strokeWidth" format="dimension" />
<!--环形的对齐方式-->
<attr name="align" format="enum">
<enum name="center" value="0" />
<enum name="left" value="1" />
<enum name="right" value="2" />
<enum name="center_horizontal" value="3" />
<enum name="center_vertical" value="4" />
</attr>
</declare-styleable>

接着来看RingView类的核心代码实现
/**
* 初始化绘制区域
*/
private void initRect() {
// 得到绘制的矩形区域
// 内圆环 默认值 其实就是左对齐的值
float left = getPaddingLeft() + strokeWidth,
top = getPaddingTop() + strokeWidth,
right = getPaddingLeft() + rSize - strokeWidth,
bottom = getPaddingTop() + rSize - strokeWidth;
switch (align) {
case TYPE_ALIGN_CENTER: // 居中
left = width / 2 - rSize / 2 + strokeWidth;
right = left + (rSize / 2 - strokeWidth) * 2;
top = height / 2 - rSize / 2 + strokeWidth;
bottom = top + (rSize / 2 - strokeWidth) * 2;
break;
case TYPE_ALIGN_LEFT: // 左对齐
break;
case TYPE_ALIGN_RIGHT: // 右对齐
right = width - getPaddingRight() - strokeWidth;
left = right - (rSize / 2 - strokeWidth) * 2;
break;
case TYPE_ALIGN_CENTER_HORIZONTAL: // 水平居中
left = width / 2 - rSize / 2 + strokeWidth;
right = left + (rSize / 2 - strokeWidth) * 2;
break;
case TYPE_ALIGN_CENTER_VERTICAL: // 垂直居中
top = height / 2 - rSize / 2 + strokeWidth;
bottom = top + (rSize / 2 - strokeWidth) * 2;
break;
}
rectF = new RectF(left, top, right, bottom);
}

关于计算 通过一张图解释



下面介绍绘制 (绘制非常简单)在 onDraw 里面

if (flag) {
for (int i = 0; i < values.length; i++) {
paint.setColor(colors[i]);
canvas.drawArc(rectF, dynamicStartAngle[i], dynamicSweepAngle[i], false, paint);
}
}


下面介绍关于动态计算角度 (核心的核心)
首先要初始化每一部分的角度

/**
* 初始化扫过角度
*
* @param sweepAngle 角度
*/
private void initSweepAngle(float[] sweepAngle) {
int total = 0;
for (int value : values) {
total += value;
}
for (int i = 0; i < values.length; i++) {
sweepAngle[i] = values[i] * 1.0f / total * 360;
}
}

其次要进行绘制
@Override
public void run() {
float currentTotalAngle = 0f;
while (currentTotalAngle < 360f) {
currentTotalAngle = 0f;
// 计算每一次绘制的每一个比例的起始角度
for (int i = 0; i < dynamicStartAngle.length; i++) {
if (i == 0) // 第一次绘制所有比例的其实角度都为0
dynamicStartAngle[i] = 0f;
else // 以后每次绘制的启示角度等于上一次的起始角度+上一次绘制的角度
dynamicStartAngle[i] = dynamicStartAngle[i - 1] + dynamicSweepAngle[i - 1];
}
// 计算每次绘制的角度
for (int i = 0; i < dynamicSweepAngle.length; i++) {
currentTotalAngle += dynamicSweepAngle[i];
if (dynamicSweepAngle[i] < sweepAngle[i]) {
dynamicSweepAngle[i] += 2f;
// 如果超过的分配值 则直接赋值为分配值
dynamicSweepAngle[i] = dynamicSweepAngle[i] >= sweepAngle[i] ? sweepAngle[i] : dynamicSweepAngle[i];
}

}
postInvalidate();
try {
Thread.sleep(66);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 绘制完成
flag = false;
}

好了到这里基本上都介绍完了

其他代码请下载源代码查看 (良心博主,不要积分,放心点击下载链接)

芝麻开门
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息