requestLayout()
和 invalidate()
是 Android 中 View 类的两个重要方法,用于不同的视图更新场景。让我解释它们的作用和区别:
- requestLayout() 方法
作用:
- 请求重新测量和布局整个视图树。
- 触发视图的 onMeasure() 和 onLayout() 方法。
- 用于视图的大小或位置发生变化时。
调用时机:
- 当视图的尺寸需要改变时。
- 当视图的位置需要改变时。
- 当视图的子视图发生增删或其布局参数变化时。
例子:
button.setVisibility(View.GONE);
parentLayout.requestLayout();
- invalidate() 方法
作用:
- 请求重绘视图。
- 触发视图的 onDraw() 方法。
- 用于视图的内容或外观需要更新,但尺寸和位置不变时。
调用时机:
- 当视图的颜色、文本内容等发生变化时。
- 当需要重新绘制自定义视图的内容时。
- 动画更新时。
例子:
textView.setTextColor(Color.RED);
textView.invalidate();
主要区别:
- 影响范围:
- requestLayout(): 可能影响整个视图层次结构的布局。
- invalidate(): 通常只影响调用它的视图及其子视图。
- 性能影响:
- requestLayout(): 开销较大,因为它可能导致整个视图树的重新测量和布局。
- invalidate(): 开销相对较小,通常只涉及重绘。
- 触发的回调:
- requestLayout(): 触发 onMeasure() 和 onLayout(),可能还会触发 onDraw()。
- invalidate(): 主要触发 onDraw()。
- 使用场景:
- requestLayout(): 用于影响视图结构或尺寸的变化。
- invalidate(): 用于视图内容或外观的更新。
- 线程安全:
- requestLayout(): 可以在非 UI 线程调用。
- invalidate(): 只能在 UI 线程调用。(非 UI 线程应使用 postInvalidate())
实际使用示例:
public class CustomView extends View {
private int mColor;
public void setColor(int color) {
mColor = color;
invalidate(); // 只需要重绘
}
public void setNewSize(int width, int height) {
getLayoutParams().width = width;
getLayoutParams().height = height;
requestLayout(); // 需要重新测量和布局
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 使用 mColor 绘制
}
}
在这个例子中,改变颜色只需要 invalidate(),而改变尺寸则需要 requestLayout()。
理解这两个方法的区别和适用场景对于优化 Android 应用的性能和创建响应式 UI 非常重要。如果你想了解更多关于如何在复杂场景中使用这些方法,或者需要更多的代码示例,我可以为你提供更详细的信息。