首先自定义view要重写onMeasure方法,在此之前,自定义了一个方法measureWidthAndHeight,代码很简单,也很容易明白
private int measureWidthAndHeight(int inputMeasureSpec){
int result = 0;
int mode = MeasureSpec.getMode(inputMeasureSpec);
int size = MeasureSpec.getSize(inputMeasureSpec);
if (mode == MeasureSpec.EXACTLY){
result = size;
}else {
result = 200;
if (mode == MeasureSpec.AT_MOST){
result = Math.min(result,size);
}
}
return result;
}
然后onMeasure调用上述方法方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = measureWidthAndHeight(widthMeasureSpec);
int height = measureWidthAndHeight(heightMeasureSpec);
setMeasuredDimension(width,height);
}
通过onMeasure设置view的高度和宽度后,使用onSizeChanged方法,实例化画笔所需要的参数:
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mRectCount = 40; //设置条形图个数
mWidth = getWidth();
mRectHeight = getHeight();
mRectWidth = (int) (mWidth*0.9/mRectCount);//设置每个条形图宽度
offset = (int) (mWidth*0.1/mRectCount);//设置相邻两个条形图之间的间距
mLinearGradient = new LinearGradient(0,0,mRectWidth,mRectHeight,Color.YELLOW,Color.BLUE, Shader.TileMode.MIRROR);
mPaint.setShader(mLinearGradient);
}
这里简单说一下LinearGradient使用,如图
整个图类似于一个view,并通过LinearGradient的最后一个参数实现重复渐变,延伸渐变,镜像渐变等效果,但是需要通过Paint来设置并画出
最后实现onDraw方法:
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i<mRectCount;i++){
super.onDraw(canvas);
double random = Math.random();
float currentHeight = (float) (mRectHeight*random);
/**
*
* 下面是画出每个图,当i=0时,第一个条形图开始的位置为mWidth*0.05+offset
* 当i=mRectCount-1时,最后一个条形图结束的位置是mWidth*0.05+mWidth*0.9=mWidth*0.95
* 近似整个图在中心
*
*/
canvas.drawRect((float)(mWidth*0.05+mRectWidth*i+offset),
currentHeight,
(float)(mWidth*0.05+mRectWidth*(i+1)),
mRectHeight,
mPaint);
}
postInvalidateDelayed(300);//每隔3毫秒重新onDraw
}
效果图如下所示: