目录
- 构造函数
- [onMeasure(int widthMeasureSpec, int heightMeasureSpec)](#onMeasure(int widthMeasureSpec, int heightMeasureSpec))
- [onDraw(Canvas canvas)](#onDraw(Canvas canvas))
- [onLayout(boolean changed, int left, int top, int right, int bottom)](#onLayout(boolean changed, int left, int top, int right, int bottom))
- [onTouchEvent(MotionEvent event)](#onTouchEvent(MotionEvent event))
- [onSizeChanged(int w, int h, int oldw, int oldh)](#onSizeChanged(int w, int h, int oldw, int oldh))
- [onAttachedToWindow() 和 onDetachedFromWindow()](#onAttachedToWindow() 和 onDetachedFromWindow())
- [onSaveInstanceState() 和 onRestoreInstanceState(Parcelable state)](#onSaveInstanceState() 和 onRestoreInstanceState(Parcelable state))
在 Android 开发中,自定义 View 是一种常用的技术,允许开发者创建具有独特外观和行为的 UI 组件。自定义 View 通常涉及重写一些关键的方法,以实现特定的绘制和交互逻辑。
构造函数
作用
构造函数用于初始化 View。通常会有三个重载的构造函数,用于不同的初始化场景。
java
public class CustomView extends View {
public CustomView(Context context) {
super(context);
init(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
// 初始化代码
}
}
onMeasure(int widthMeasureSpec, int heightMeasureSpec)
作用
该方法用于测量 View 的大小。开发者需要在这个方法中计算 View 的宽度和高度,并调用 setMeasuredDimension(int measuredWidth, int measuredHeight) 来设置测量结果。
java
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;
// 根据测量模式和给定的尺寸来计算 View 的宽高
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(200, widthSize); // 假设最大宽度为 200
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(200, heightSize); // 假设最大高度为 200
}
setMeasuredDimension(width, height);
}
onDraw(Canvas canvas)
作用
该方法用于绘制 View 的内容。开发者需要在这个方法中使用 Canvas 对象来绘制图形、文本或其他内容。
java
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
// 绘制一个红色的圆
canvas.drawCircle(getWidth() / 2, getHeight() / 2, Math.min(getWidth(), getHeight()) / 2, paint);
}
onLayout(boolean changed, int left, int top, int right, int bottom)
作用
该方法用于布局 View 的子视图。自定义 ViewGroup 通常需要重写这个方法,以确定每个子视图的位置和大小。
java
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int childCount = getChildCount();
int currentTop = top;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childHeight = child.getMeasuredHeight();
child.layout(left, currentTop, right, currentTop + childHeight);
currentTop += childHeight;
}
}
onTouchEvent(MotionEvent event)
作用
该方法用于处理触摸事件。开发者可以在这个方法中实现自定义的触摸交互逻辑。
java
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 处理按下事件
return true;
case MotionEvent.ACTION_MOVE:
// 处理移动事件
return true;
case MotionEvent.ACTION_UP:
// 处理抬起事件
return true;
}
return super.onTouchEvent(event);
}
onSizeChanged(int w, int h, int oldw, int oldh)
作用
该方法在 View 的大小发生变化时调用。开发者可以在这个方法中处理与尺寸变化相关的逻辑。
java
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 处理尺寸变化的逻辑
}
onAttachedToWindow() 和 onDetachedFromWindow()
作用
onAttachedToWindow() 在 View 被附加到窗口时调用,可以在这里进行一些资源的初始化。
onDetachedFromWindow() 在 View 从窗口分离时调用,可以在这里进行一些资源的释放
java
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// 资源初始化
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 资源释放
}
onSaveInstanceState() 和 onRestoreInstanceState(Parcelable state)
作用
用于保存和恢复 View 的状态,通常在需要处理配置变化(如屏幕旋转)时使用。
java
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
// 保存自定义状态
return superState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
// 恢复自定义状态
}