看书的时候,看到了一个模仿音乐音频条的例子,就敲了一下,效果还可以。先看下效果
1. 实现思路
自定义一个视图,然后在onDraw()方法中绘制几个长方形的条,让长方形的长条随机变化,然后重复绘制,就有了这样的效果。
2. 自定义View
public class MusicLinearClip extends View {
private int mWidth;
private int mHeight;
private int mCurrentHeight;
private int mRectWidth;
private int mRectCount = 6;
private Paint mPaint;
//线性渐变
private LinearGradient linearGradient;
private int offset = 8;//条形之间的间隔
//如果view想要应用wrapContent,就必须重写onMeasure方法
public MusicLinearClip(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
mPaint = new Paint();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
//mWidth这里面等于屏幕的宽度,控件的宽度为充满整个布局
mWidth = getWidth();
mHeight = getHeight();
System.out.println("width="+mWidth+",height="+mHeight);
//每个长方条的宽度
mRectWidth = (int) (mWidth*0.6/mRectCount);
//他这个参数的意思是:既然是渐变的线,那么这个线是有宽度的,所以会有开始和结束的坐标
linearGradient = new LinearGradient(
0,
0,
mRectWidth,
mHeight,
Color.BLUE,
Color.YELLOW,
Shader.TileMode.CLAMP
);
mPaint.setShader(linearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
for (int i = 0; i < mRectCount; i++) {
mCurrentHeight = (int)( Math.random()*mHeight);
float left = (float) (mRectWidth*i+mWidth*0.2+offset);
float top = mCurrentHeight;
float right = (float) (mRectWidth*(i+1)+mWidth*0.2);
float bottom = mHeight;
//这里犯错的原因是我把他参数的意思给理解错了,left,top指得是左上角的横纵坐标,bottom,right指得是右下角的横纵坐标
//他的坐标系箭头是向下的,当right的值小于left的值,bottom的值小于top的值时,这时候将不会绘制任何图形
canvas.drawRect(left, top, right, bottom, mPaint);
}
postInvalidateDelayed(300);
}
}
上面代码中 有一个canvas.drawRect(left, top, right, bottom, mPaint);
3. 那么这些音频条该如何绘制呢
这样的方法,其中:left,top是左上角的横纵坐标,right,bottom是右下角的横纵坐标,这样就能唯一确定一个长方形。
float left = (float) (mRectWidth*i+mWidth*0.2+offset);
float top = mCurrentHeight;
float right = (float) (mRectWidth*(i+1)+mWidth*0.2);
float bottom = mHeight;
我们把bottom 的高度设置为屏幕的高度,这样绘制出来的图形他就会到达屏幕的最下角了。
4. 让绘制出来长方条之间有间隔,有俩种方式可以实现
第一种:left=(mRectWidth*i+mWidth*0.2+offset);
right= (float) (mRectWidth*(i+1)+mWidth*0.2);
offset为设置的间隔
如果不加offset的话,上面的公式是没有间距的,当加了offset,虽然长条的宽度变短了,但是变短的距离刚好为我们想要设置的间距。
第二种方法需要判断是不是绘制第一次,如果是第一次就不加间隔,其他的话,left需要加间隔。
Demo下载:链接