一个关于view部分方法的介绍
public class MyView extends View { public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } /** * View测量 * EXACTLY:精确模式,指定具体数值。 * AT_MOST:最大模式,此时控件尺寸只要不超过父控件允许的最大值就可。 * UNSPECIFIED:不指定大小测量模式,通常情况下在绘制自定义view才使用。 * view默认onMeasure方法只支持EXACTLY,所以如果自定义如果不重写onMeasure方法 * 控件可以响应指定的具体宽高或者match_parent,如果要支持wrap_content就必须重写来指定wrap的大小 * * @param measure * @return */ private int measureWidth(int measure) { // MeasureSpec是一个32为的int值,使用位运算,是为了提高并优化效率。 int result = 0; // 提取测量模式和大小 int specMode = MeasureSpec.getMode(measure); int specSize = MeasureSpec.getSize(measure); // 通过测量模式给出不同的测量值,当模式为EXACTLY,直接赋值 if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { // 为其它模式时,先设置一个默认值,与默认值比较 result = 200; if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } private int measureHeight(int measure) { int result = 0; // 提取测量模式和大小 int specMode = MeasureSpec.getMode(measure); int specSize = MeasureSpec.getSize(measure); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = 200; if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } /** * 绘图 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.start); canvas.drawBitmap(bitmap, 0, 0, null); canvas.drawBitmap(bitmap1, 0, 0, null); } // 从xml加载组建后回调 @Override protected void onFinishInflate() { super.onFinishInflate(); } // 组件大小改变时回调 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } // 回调该方法来确定现实的位置 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } // 监听到触摸事件时回调 @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } }
自定义view一个音频跳动图的绘制
代码部分:
public class MyRedioBit extends View { private double random; private int mWidth; private int mRectheight; private int mRectWidth; private Paint paint; public MyRedioBit(Context context) { super(context); } public MyRedioBit(Context context, AttributeSet attrs) { super(context, attrs); } public MyRedioBit(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private int mRectCount = 12; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int offset = 10; for (int i = 0; i < mRectCount; i++) { random = Math.random(); float currentHeight = (float) (mRectheight * random); canvas.drawRect((float) (mWidth * 0.4 / 2 + mRectWidth * i + offset) , currentHeight, (float) (mWidth * 0.4 / 2 + mRectWidth * (i + 1)), mRectheight, paint); } // 通知view进行重绘 // invalidate(); // 延迟绘制,每隔300ms进行重绘 postInvalidateDelayed(300); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getWidth(); mRectheight = getHeight(); mRectWidth = ((int) (mWidth * 0.6 / mRectCount)); // 设置阴影 LinearGradient linearGradient = new LinearGradient(0, 0, mRectWidth, mRectheight, Color.YELLOW, Color.BLUE, Shader.TileMode.CLAMP); paint = new Paint(); paint.setShader(linearGradient); } }