这已经是第二次实现这种效果了。记录下来。
首先看下效果图。这里就不搞gif 了
1、首先确定需要音频条得数量
2、根据大小计算出 间距和音频条得宽度
3、绘制初始样式
4、利用handler消息机制 每隔一段时间重新计算高度并绘制
直接上代码吧。都写好注释了。懒得分步写了。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MusicView extends View {
private Paint mPaint;//画笔
private int mLineNum;// 跳动得音频效果数量
private float mLineWidth;// 竖线得宽度
private int mPaintColor;//画笔得颜色
private float originX,originY;//原点坐标
private float space;// 间隔
private List<Float> mLineHeightList;
private Random random;
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
reckonHeight();
mHandler .sendEmptyMessageDelayed(1,200);
break;
}
}
};
public MusicView(Context context) {
super(context);
}
public MusicView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public MusicView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initView();
}
public void initView(){
mLineHeightList = new ArrayList<>();
mPaintColor = Color.argb(255,0,38,255);//这里先设置蓝色
mPaint = new Paint();
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setDither(true);//是否使用图像抖动a
mPaint.setColor(mPaintColor);
//STROKE //描边
//FILL //填充
//FILL_AND_STROKE //描边加填充
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);//圆角
mPaint.setStrokeWidth(5f);
mLineNum= 4;
setBackgroundColor(Color.WHITE);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//获取原点的x坐标,也就是画布左上角的坐标。这里减去了paddingBottom的距离
originY = getHeight() - getPaddingBottom();
if (mLineHeightList != null)
mLineHeightList.clear();
for (int i = 0; i < mLineNum; i++) {
//初始高度是一半
mLineHeightList.add((float) ((getHeight()-getPaddingBottom()-getPaddingTop())/2));
}
//计算预计画几个 这里乘1.5倍 要求多出一半的距离用于竖线的间隔
mLineWidth = (float) ((getWidth()-getPaddingLeft()-getPaddingRight())/(mLineNum*1.5));
// 计算间距 空白的地方是比实际画线多一条, 先求出留白的宽度 除于 画线数+1
space = (mLineWidth*mLineNum/2)/(mLineNum+1);
//设置画笔的宽度。 //用画线的方式实现 柱状图
mPaint .setStrokeWidth(mLineWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
originX = 0f+getPaddingLeft();//最初始的X 坐标
for (int i=0;i<mLineHeightList.size();i++){
//= = space 太短 第一条线太靠近左侧 这里加上画笔宽度的一半
canvas.drawLine(space+originX+i*(space+mLineWidth)+mLineWidth/2,mLineHeightList.get(i),space+originX+i*(space+mLineWidth)+mLineWidth/2,originY,mPaint);
// canvas.drawRect(space+originX+i*(space+mLineWidth),mLineHeightList.get(i),space+originX+i*(space+mLineWidth)+mLineWidth,originY,mPaint);
}
}
public void reckonHeight(){
if (null ==random){
random = new Random();
}
//利用0~1的随机数 乘以 可绘制区域的高度。作为每个竖线的高度。
if (mLineHeightList!=null)
mLineHeightList.clear();
for (int i = 0; i < mLineNum; i++) {
//初始高度是一半
mLineHeightList.add((float) (0.1 * (random.nextInt(10) + 1) * (getHeight() - getPaddingBottom() - getPaddingTop())));
}
invalidate();
}
public void startAnim(){
mHandler.sendEmptyMessage(1);
}
public void stopAnim(){
mHandler.removeCallbacksAndMessages(null);
}
}
使用方式: