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 非常重要。如果你想了解更多关于如何在复杂场景中使用这些方法,或者需要更多的代码示例,我可以为你提供更详细的信息。