Jetpack Compose 查找父级宽度/长度

Mar*_*tin 31 layout android android-jetpack-compose

我想显式检索fillMaxSize().
假设我有:

        Box(Modifier
                .fillMaxSize()
                .background(Color.Yellow)) 
        {
    var size = ?
    Box(Modifier
                .size(someSize)
                .background(Color.Blue))
        {Text("Test")}
Run Code Online (Sandbox Code Playgroud)

我想多次更改第二个 Box 的大小(可能源于某些视图模型),然后将其重置为 maxSize。

我怎样才能做到这一点?我不知道任何“getMaxSize()”方法?

Phi*_*hov 50

如果您确实需要原始大小值,可以使用以下代码:

    var size by remember { mutableStateOf(IntSize.Zero) }
    
    Box(Modifier
        .fillMaxSize()
        .background(Color.Yellow)
        .onSizeChanged {
            size = it
        }
    ) {
        Box(
            Modifier
                .then(
                    with(LocalDensity.current) {
                        Modifier.size(
                            width = size.width.toDp(),
                            height = size.height.toDp(),
                        )
                    }
                )
                .background(Color.Blue)
        ) { Text("Test") }
    }
Run Code Online (Sandbox Code Playgroud)

但请注意,就性能而言,它并不是最佳的:此视图会渲染两次。第一次第二个框的大小为零,然后onSizeChanged调用块,然后第二次渲染视图。

如果remember在顶级视图中使用,请特别小心,因为更改状态将触发全视图堆栈重新渲染。通常您希望将屏幕分割为具有状态的视图,因此仅更改一个视图状态就会重新渲染该视图。

您也可以在 中BoxWithConstraints使用maxWidth/ :它的代码少得多,性能也好一些。maxHeightBoxWithConstraintsScope

BoxWithConstraints(
    Modifier
        .fillMaxSize()
        .background(Color.Yellow)
) {
    Box(
        Modifier
            .size(
                width = maxWidth,
                height = maxHeight,
            )
            .background(Color.Blue)
    ) { Text("Test") }
}
Run Code Online (Sandbox Code Playgroud)

但通常如果您想指示大小依赖性,在不直接知道大小的情况下使用修饰符就足够了。这是一种更“组合”的编写代码的方式,也是一种更优化的方式。

因此,如果您希望第二个盒子与第一个盒子大小相同,也可以使用.fillMaxSize()它。如果你希望它成为父级的一部分,你可以添加分数参数。要使第二个盒子的大小为第一个盒子大小的一半,您可以:

Box(
    Modifier
        .fillMaxSize(fraction = 0.5f)
) { Text("Test") }
Run Code Online (Sandbox Code Playgroud)

如果您想要不同的宽度/高度部分:

Box(
    Modifier
        .fillMaxWidth(fraction = 0.3f)
        .fillMaxHeight(fraction = 0.7f)
) { Text("Test") }
Run Code Online (Sandbox Code Playgroud)


Gab*_*tti 24

在第一个中,Box您可以使用onGloballyPositioned修饰符来获取size. 当内容的全局位置可能发生变化时,
它会在布局的最终​​版本中被调用。LayoutCoordinates

然后使用coordinates.size来获取第一个 的大小Box

var size by remember { mutableStateOf(Size.Zero)}

Box(
    Modifier
        .fillMaxSize()
        .background(Color.Yellow)
        .onGloballyPositioned { coordinates ->
            size = coordinates.size.toSize()
        }
        Box(){ /*....*/ }
)
Run Code Online (Sandbox Code Playgroud)