还是和上一篇一样,先上效果图

android 音频柱动画 音频动画图_Android


这次要比上次难了点,

首先我们把自定义文件贴上

/**
 * 作者:chengxiangtong 
 * 仿音频条
 */

public class AudioView extends View {
        private Random mttt = new Random();    private Paint mPaint;
private int width;
private int height;
private int mRectWidth = 10;
private int mRectHeight = 60;
private int offset = 3;//每次画之前的左边距离
public AudioView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);        init();    }    public AudioView(Context context) {        this(context, null);    }    public AudioView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    private void init() {        mPaint = new Paint();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);	//获取padding        int left = getPaddingLeft();        int top = getPaddingTop();        int right = getPaddingRight();        int bottom = getPaddingBottom();        width = getMeasuredWidth() - left - right;        height = getMeasuredHeight() - top - bottom;        int mRectCount = 0;        for (int count = 5; count < width; count += mRectWidth) {            mRectCount++;        }        for (int i = 0; i < mRectCount; i++) {            double mRandom = Math.random();
	    //随机数产生各种画笔的颜色,当然你也可以在初始化的时候固定一种颜色            int n = mttt.nextInt(4);            if (n == 0) {                mPaint.setColor(Color.BLUE);            } else if (n == 1) {                mPaint.setColor(Color.RED);            } else if (n == 2) {                mPaint.setColor(Color.LTGRAY);            } else {                mPaint.setColor(Color.GREEN);            }            mRectHeight = (int) (mRandom * height);//获取每次随机的高度            canvas.drawRect(offset + mRectWidth * i, mRectHeight, mRectWidth * (i + 1), height, mPaint);        }        postInvalidateDelayed(500);//每间隔500ms刷新一次,这样才有动的效果    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthsize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(getMeasuredWidth() / 2, getMeasuredHeight() / 2);        } else if (widthMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(getMeasuredWidth() / 2, heightSize);        } else if (heightMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(widthsize, getMeasuredHeight() / 2);        }    }}

这个主要说说onMeasure()这个方法,这个是来测试布局的,下面就是他的全部意思啦:

setMeasuredDimension(int, int)设置实际大小。

)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。

UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。


MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。

MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。

MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

所以你现在对于这段代码就不陌生了

if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(getMeasuredWidth() / 2, heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthsize, getMeasuredHeight() / 2);
        }



分别表示什么自己对照就好了

,在布局中直接调用就可以啦,不在给贴布局啦,实在是不好意思,浪费时间呀,有没有发现比第一篇还简单呀,自己可以运行看看啦

github地址:https://github.com/xiangtongcheng/customerView