compose中为什么RED区域是50dp的理解

3 阅读3分钟

compose中为什么RED区域是50dp的理解

    Box(
        Modifier
            .background(color = Color.Green)
            .requiredSize(100.dp)
            .background(color = Color.Red)
            .requiredSize(50.dp)
            .background(color = Color.Blue)
    )

问题的核心:约束是向上报告的,绘制是向下接收的

您引用的文档是正确的,但它描述的是 父级向更上层报告尺寸 的行为,而不是 父级向子级分配绘制区域 的行为。

我们来分析这个 Modifier 链中的两个关键步骤:

步骤 1: 尺寸的测量与报告(由右向左)

在测量阶段,Compose 询问每个 Modifier 的子级(链条右侧的部分)希望有多大。

I. C + D 的测量结果
  • B 施加的约束 (100dp): B 向 C 施加的约束是 100dp x 100dp。
  • D 施加的约束 (50dp): C 几乎将 100dp 的约束传递给 D。D 强制要求其内容为 50dp x 50dp。
  • C + D 的最终尺寸报告: D(以及 C)向它们的父级 B 报告的测量结果是 50dp x 50dp
II. B 处的尺寸矫正(Coercion)
  • B 的期望: B (requiredSize(100.dp)) 期望它的内容(C + D)是 100dp x 100dp。
  • B 的接收: B 收到内容(C + D)报告的尺寸是 50dp x 50dp。
  • 文档规则生效: B 的内容尺寸 (50dp) 不满足 B 的约束 (100dp)。
    • 结果: B 将它报告给更上层(即 A)的尺寸矫正为 100dp x 100dp

结论: 最终整个 Box 的总尺寸是 100dp x 100dp。但是,这个矫正操作(从 50dp 变为 100dp)只发生在 B 向上报告时,它并没有改变 C + D 的实际测量尺寸

步骤 2: 绘制阶段与画布尺寸(由左向右)

绘制修改器(background)的绘制区域大小取决于它所包装内容的实际测量尺寸

I. C (background(Color.Red)) 的绘制
  • C 的画布尺寸: C 绘制在它所包装内容(即 D + Box内容)的测量尺寸上。
  • C 内部知道它下面的内容 (.requiredSize(50.dp)) 的实际测量结果50dp x 50dp
  • 结果: background(Color.Red) 使用 50dp x 50dp 作为画布尺寸,绘制一个 50dp x 50dp 的红色矩形
II. 最终布局呈现
  • Box 最终被分配了 100dp x 100dp 的空间(由 B 的矫正决定)。
  • 内部的 Box 内容 (即 C + D) 自身只占据了 50dp x 50dp。
  • 系统会根据 Box 的默认对齐方式(通常是左上角)将这个 50dp 的红色区域放置在 100dp 的画布上。
  • A (background(Color.Green)) 绘制在整个 100dp x 100dp 的区域上。

总结:为什么 Red 是 50dp

  1. Red (C) 的绘制区域 等于其后续内容 D 报告的实际尺寸50dp
  2. Green (A) 的绘制区域 等于整个 Composable 的 最终分配尺寸(由 B 矫正后):100dp

因此,你看到的结果是:

  • 一个 100dp x 100dp 的绿色背景(由 A 绘制)。
  • 在这个绿色背景的左上角,有一个 50dp x 50dp 的红色矩形(由 C 绘制),它覆盖了部分绿色区域。

所以,background(Color.Red)50dp,因为这是它被测量出的尺寸,矫正尺寸 (100dp) 仅用于向父级报告,而 不会反馈给绘制修改器作为新的画布尺寸