Android compose ModalBottomSheetLayout 在内容大小变化时跳转

use*_*854 25 android bottom-sheet android-jetpack android-jetpack-compose

我基本上遇到了与这篇文章相同的问题,只不过我使用的是 Jetpack Compose,而不是旧的 View 模型。任何类型的内容都会发生这种情况 - 我用一个简单的Text可组合项对其进行了测试。重现方法如下:

  1. 设置Text可组合项以显示最终使其高 6 行的字符串
  2. 将文本更改为仅 1 行高(同时底部工作表保持展开状态)。在我的测试用例中,我只是这样做,以便单击文本会更改它
  3. 可组合项的顶部Text保持在先前的水平,底部瞬间“跳”起来以弥补高度差。然后整个可组合项下降,最终到达屏幕底部,它本来应该在的地方

仅当新内容的高度比原始内容短时才会发生这种情况(这就是为什么我用 6 行文本更改为 1 行来测试它)。我引用的原始帖子说解决方案是 set android:animateLayoutChanges = "false",但是,我在 Compose 中没有看到任何等效的内容。有一个修饰符animateContentSize,但它仅用于启用动画。我没有看到任何禁用它的选项。

这是我的示例代码:

ModalBottomSheetLayout(
        sheetContent = {
            var text by remember{ mutableStateOf("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum")}
            Text(text = text, Modifier.clickable {
                text = "a much shorter line of text"
            })
        },
        sheetShape = RoundedCornerShape(12.dp),
    ) { ... }
Run Code Online (Sandbox Code Playgroud)

ngl*_*ber 0

我认为你可以用来SubcomposeLayout测量文本的最大高度。然后,使用子组合中计算的最大高度用 aText包裹。Box

您可以使用下面的可组合函数作为sheetContent参数。

@Composable
fun BottomSheetContent() {
    var maxHeight = remember { 0.dp }
    var text by remember { mutableStateOf("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum") }

    val localDensity = LocalDensity.current
    SubcomposeLayout { constraints ->
        // Measuring the Text size...
        val contentPlaceable = subcompose("SomeRandomIdForThisContent") {
            Text(text = text,
                Modifier
                    .clickable {
                        text = "a much shorter line of text"
                    }
            )
        }.first()
            .measure(constraints)
        val height = contentPlaceable.height
        val heightInDp = with(localDensity) { ((height + 1) / density).dp }
        // Updating the max height
        if (maxHeight == 0.dp || heightInDp > maxHeight) {
            maxHeight = heightInDp
        }

        layout(contentPlaceable.width, maxHeight.roundToPx()) {
            contentPlaceable.placeRelative(0, 0)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述