如果我不将其包装在其他容器中,为什么 Surface 子项可兼容填充最大尺寸?

Chi*_*may 5 android android-jetpack-compose

如果我指定尺寸为 ,则此代码将填满整个屏幕100.dp

ComposeTheme {
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Box(
            modifier = Modifier
                .width(100.dp)
                .height(100.dp)
                .clip(RoundedCornerShape(12.dp))
                .background(color = Color.Red)
        ) {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码通过填充所需的大小来正常运行。

ComposeTheme {
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Column(modifier = Modifier.fillMaxSize()) {
            Box(
                modifier = Modifier
                    .width(100.dp)
                    .height(100.dp)
                    .clip(RoundedCornerShape(12.dp))
                    .background(color = Color.Red)
            ) {

            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下为什么会发生这种情况吗?

Phi*_*hov 6

这就是参数设置Box为 时的工作原理。正在幕后使用它。propagateMinConstraintstrueSurface

例如,当 的内容无法直接指定修饰符并且需要为 的内容设置最小大小时,设置propagateMinConstraints为可能很有用。如果设置为,则在 上设置的最小尺寸也将应用于内容,否则最小尺寸将仅应用于 Box。trueBoxBoxpropagateMinConstraintstrueBox

因此,第一级Surface子级的最小大小约束等于 的大小Surface

以下是一位维护者如何解释这一决定的原因:

Surface并不是真正的布局。我们遇到了这样的问题FloatingActionButton- 我们根据规范设置了最小宽度和高度,但用户可以根据需要设置更大的尺寸。现在里面的内容(图标)FloatingActionButton需要填充整个尺寸,Surface所以我们在上面应用一个波纹,然后波纹被形状剪掉Surface。如果我们只是设置Modifier.fillMaxSize()它会填满整个屏幕,因为FloatingActionButton没有指定最大尺寸。并且由于系统的工作方式,没有这样Modifier.fillMinSize()的信息不会被传播。Box所以我们想出了一个propagateMinConstraints=true主意,现在里面的内容Surface必须填充应用到的最小大小Surface。老实说,我不确定解释是否足够清楚:)。但是,是的,如果您需要一些真实的布局和多个元素,Surface您需要手动添加它,所以添加您自己的Box.

它可以被Modifier.requiredSize, 或者 覆盖,就像您在第二个代码示例中所做的那样 - 通过使用其他容器。在您的示例Column中, 的大小仍然等于parent Surface