开年来公司不忙,就在闲逛时朋友说给写给小控件,并给出这样的效果:
我问他还要什么要求,提供的数据是什么,他竟然告诉我没要求,数据随机给就行。我的第一反应是这还不简单啊,就写个view简单画一下不就好了,于是上来就开写,但是写着写着发现还是有些麻烦,麻烦点就在他竟然不给数据。下面在这个控件编写过程记录下来。
效果如下:
首先看到这样一个效果时,需要确定这个view哪些属性支持定制。我给出的自定义属性包括:柱形条个数,柱形条宽度,柱形条颜色(支持设置颜色组),波动节奏快慢,柱形条间隙(由控件宽度、柱形条个数、柱形条宽度共同决定)。
于是控件有了如下属性:
/**
* 单根柱形宽度,默认为10
*/
private int pillarWidth = 10;
/**
* 柱形数量,默认为4
*/
private int pillarAmount = 4;
/**
* 柱形颜色
*/
private int pillarColor = Color.rgb(179, 100, 53);
/**
* 波动节奏
* 快-慢 0-1
*/
private double rhythm = 0.5;
/**
* 柱形颜色组,
* 当pillarColors等于pillarAmount时,对应柱形取pillarColors对应颜色
* 当pillarColors大于pillarAmount时,对应柱形取pillarColors前pillarAmount个对应颜色
* 当pillarColors小于pillarAmount时,pillarColors循环拼接后,对应柱形取pillarColors对应颜色
*/
private int[] pillarColors;
开始画view前需要确定view大小:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//设置控件宽度
setMeasuredDimension(measureWidth(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
//控件内容宽度
contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
//控件内容高度
contentHight = getHeight() - getPaddingTop() - getPaddingBottom();
//控件的左、上、右、下坐标
left = getPaddingLeft();
top = getPaddingTop();
right = getWidth() - getPaddingRight();
bottom = getHeight() - getPaddingBottom();
//柱形条间隙
gap = pillarAmount > 1 ? (float) (contentWidth - pillarAmount * pillarWidth) / (float) (pillarAmount - 1) : 0;
//初始化属性动画值数组
this.animValues = new float[pillarAmount];
//初始化波动实体数组
this.waves = new Wave[pillarAmount];
for (int i = 0; i < waves.length; i++)
{
int distance = (int) (Math.random() * contentHight);
waves[i] = new Wave(-1, distance, bottom, bottom - distance);
}
}
/**
* 计算控件宽度
* @param measureSpec
* @return
*/
private int measureWidth(int measureSpec)
{
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
//根据柱形数量跟宽度计算出最小宽度
int minWidth = pillarWidth * pillarAmount + getPaddingLeft() + getPaddingRight();
if (specMode == MeasureSpec.EXACTLY)
{
return specSize > minWidth ? specSize : minWidth;
}
return minWidth;
}
21行animValues用来记录每个柱形条属性动画的动画值;
23行waves用来记录每次波动的波动情况情况;
25-28行为waves赋初始值(柱形条都在最低端,都向上运动,运动范围都为控件的内容区域高度contentHight)。
下面看一下Wave对象:
/**
* 波动实体类
*/
class Wave
{
/**
* 波动