1

背景

我正在制作一个桌面撰写应用程序。

我有一个分开的项目LazyColumn。的宽度可能不适合窗口,所以我通过将其封闭在with修饰符集内来实现水平滚动。DividerLazyColumnLazyColumnBoxhorizontalScroll()

现在LazyColumn也可以水平滚动了。但奇怪的Divider是,分隔项目的 ' 消失了。

在深入研究了一段时间后,我发现它Divider只有在放置在水平滚动的父级中时才变得不可见。


最小复制

这是观察到的行为的最小再现,其中当修饰符设置为封闭时,红色Divider明显不可见horizontalScroll(rememberScrollState())Box

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        Box(
            Modifier.fillMaxSize()
                .background(Color.Green)
                .horizontalScroll(rememberScrollState())
        ) {
            Divider(thickness = 10.dp, color = Color.Red)
        }
    }
}

水平滚动,分隔线是看不见的!

可以看出,红色对于上面的代码Divider不可见的。


预期输出:

verticalScroll()或没有滚动修饰符都可以按预期工作。

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        Box(
            Modifier.fillMaxSize()
                .background(Color.Green)
                .verticalScroll(rememberScrollState())
        ) {
            Divider(thickness = 10.dp, color = Color.Red)
        }
    }
}

正如预期的那样,分隔线是可见的

Divider按预期正确输出,上面的代码清晰可见红色。


版本信息

kotlin("jvm") version "1.5.21"
id("org.jetbrains.compose") version "1.0.0-alpha3"

我想知道这是否是一个错误?或者有没有办法解决这个问题。

4

1 回答 1

1

,这不是错误。

Divider用于获取全宽,就像任何其他带有fillMaxWidth()修饰符的视图一样。

但是里面horizontalScroll这个修饰符被忽略了,因为它有歧义:horizontalScroll包裹了内容的大小,所以maxWidth这个区域的约束是无限的。

fillMaxWidth 文档

如果传入的最大宽度是Constraints.Infinity这个修饰符将没有效果。

我还没有找到任何提到horizontalScrolleffects的文档Constraints,你可以看到维护者对同一问题的回答,或者你可以像这样自己测试它:

Box {
    BoxWithConstraints(Modifier.fillMaxSize()) {
        // output 1080 2082
        println("non scrollable max dimensions: ${constraints.maxWidth} ${constraints.maxHeight}")
    }
    BoxWithConstraints(Modifier.fillMaxSize().horizontalScroll(rememberScrollState())) {
        // output 2147483647 2082
        println("scrollable max dimensions: ${constraints.maxWidth} ${constraints.maxHeight}")
    }
}

在这种情况下,您需要明确指定宽度,例如:

Box(
    Modifier
        .fillMaxSize()
        .background(Color.Green)
        .horizontalScroll(rememberScrollState())
) {
    var width by remember { mutableStateOf(0) }
    val density = LocalDensity.current
    val widthDp = remember(width, density) { with(density) { width.toDp() } }
    LazyColumn(
        modifier = Modifier.onSizeChanged {
            width = it.width
        }
    ) {
        items(100) {
            Text("$it".repeat(it))
            Divider(
                thickness = 10.dp,
                color = Color.Red,
                modifier = Modifier.width(widthDp)
            )
        }
    }
}

请注意,当您的顶部LazyColumn小于底部时,例如在我的示例中,宽度一开始会更小(仅容纳可见部分),但向下和向上滚动后,宽度将不会恢复到它的原始宽度,因为Divider宽度修改器不会让它缩回。如果您需要防止这种情况,您需要仅根据可见元素计算“宽度”,这比较复杂。

于 2021-10-01T06:21:22.723 回答