Jetpack Compose 查找父级宽度/长度

问题描述 投票:0回答:3

我想显式检索

fillMaxSize()
的值。
假设我有:

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

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

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

android layout android-jetpack-compose
3个回答
46
投票

如果确实需要原始尺寸值,可以使用以下代码:

    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") }
    }

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

onSizeChanged
块,然后第二次渲染视图。

在顶级视图中使用

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

您还可以使用

BoxWithConstraints
,您可以在
maxWidth
中获得
maxHeight
/
BoxWithConstraintsScope
:代码更少,性能更好。

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

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

因此,如果您希望第二个盒子与第一个盒子大小相同,也只需在其上使用

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

Box(
    Modifier
        .fillMaxSize(fraction = 0.5f)
) { Text("Test") }

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

Box(
    Modifier
        .fillMaxWidth(fraction = 0.3f)
        .fillMaxHeight(fraction = 0.7f)
) { Text("Test") }

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(){ /*....*/ }
)

1
投票
Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                var parentSize by remember {
                    mutableStateOf(Size.Zero)
                }
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .aspectRatio(1f)
                        .background(Color.Green)
                ) {
                    Box(
                        modifier = Modifier
                            .size(100.dp)
                            .align(Alignment.Center)
                            .background(Color.Red)
                            .onGloballyPositioned {
                                //here u can access the parent layout coordinate size
                                parentSize = it.parentLayoutCoordinates?.size?.toSize()?: Size.Zero
                            }
                    ) {
                        Column(Modifier.fillMaxSize()) {
                            Text(text = "parent size  = $parentSize")
                        }
                    }
                }
            }

© www.soinside.com 2019 - 2024. All rights reserved.