如何在运行时获取 Composable 的大小?

21

我举一个例子,以下是一个可组合的函数:

@Composable
fun CustomCanvas(
) {
   Box(
      Modifier
        .aspectRatio(1.33f)
        .fillMaxWidth())
} 

合成后如何知道该对象的大小?

为什么我想知道: 我正在尝试调整并放置画布上的图像。这需要知道画布的大小。不过,我不想硬编码画布的大小。应该如何做到这一点?


1
请查看此链接:https://developer.android.com/jetpack/compose/layout#constraints - Sinner of the System
谢谢!最终在Box Composable中使用了一个BoxWithConstraints。 - user3872620
不要忘记将其转换为Dp,代码如下:with(localDensity){ coordinates.size.height.toDp() } - Jeevan Rupacha
3个回答

37

您可以使用 onGloballyPositioned 修饰符:

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

Box(Modifier.onGloballyPositioned { coordinates ->
    size = coordinates.size
}) {
   //...
}

另外,Canvas 具有 DrawScope,它具有 size 属性。

Canvas() {
    val canvasSize = size    
}

3
你可以采用几种方法。由于名称描述了它返回的是“约束条件”,因此BoxWithConstraints并不总是返回正确的大小。 约束条件最大宽度或高度并不总是与您的组合对象的宽度或高度匹配。
使用带有可变状态的Modifier.onSizeChanged{size:IntSize}或Modifier.onGloballyPositioned{}会导致另一次重新组合,这可能会导致下一帧中UI发生变化。
你可以查看这个答案,了解如何在不重新组合的情况下获取确切的大小,并在每个场合上获得确切的大小。

1

您可以使用Modifier.onSizeChanged()在运行时查找组合内容的大小。

@Composable
fun Sample() {
    Text(
        "Hello",
        Modifier.onSizeChanged {
            println("Width of Text in dp: ${it.width.toDp}")
            println("Height of Text in dp: ${it.height.toDp}")
        }
    )
}

val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()

请为您的代码添加一些解释。 - user67275
当然。我刚刚做了。 - Tatsuya Fujisaki
这个函数被称为 toDp,但它并不产生 DP,请纠正这个错误。 - alfietap
如果您在dp中设置文本的宽度或高度,则会打印相同的值。 - Tatsuya Fujisaki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接