简体   繁体   English

当放置在具有 horizontalScroll 修饰符集的可组合项内时,分隔符可组合项变得不可见。 这是一个错误吗?

[英]Divider composable becomes invisible when placed inside composable with horizontalScroll modifier set. Is this a bug?

Background背景

I am making a desktop compose application.我正在制作桌面撰写应用程序。

I had a LazyColumn with Divider separating items.我有一个带有Divider项的LazyColumn LazyColumn 's width may not fit in window so I made the LazyColumn horizontally scrollable by enclosing it inside a Box with horizontalScroll() modifier set. LazyColumn的宽度可能不适合 window,所以我通过将LazyColumn封装在一个带有 horizontalScroll horizontalScroll()修饰符集的Box中,使它可以水平滚动。

Now LazyColumn became horizontal scrollable as well.现在LazyColumn也可以水平滚动了。 But strangely the Divider 's separating the items disappeared.但奇怪的是, Divider物品的分隔线消失了。

After digging into it for a while, I figured out that Divider 's became invisible only when placed inside a horizontally scrollable parent.深入研究了一段时间后,我发现Divider仅在放置在可水平滚动的父对象中时才变得不可见。


Minimal Reproduction最小复制

Here is a minimal reproduction of observed behavior where red Divider is clearly invisible when horizontalScroll(rememberScrollState()) modifier is set in enclosing Box .这是观察到的行为的最小再现,其中当在封闭的Box中设置 horizontalScroll horizontalScroll(rememberScrollState())修饰符时,红色Divider明显不可见

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

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

As it can be seen that the red Divider is invisible for above code.可以看出,红色Divider符对于上面的代码是不可见的。


Expected Output:预计 Output:

With verticalScroll() or no scroll modifier at all works fine as expected.使用verticalScroll()或根本没有滚动修饰符都可以正常工作。

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

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

Correct output as expected, the red Divider is clearly visible for above code.按预期更正Divider ,上面代码中的红色分隔线清晰可见


Version info版本信息

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

I'd like to know if this is a bug?我想知道这是否是一个错误? or is there a way to fix this.或者有没有办法解决这个问题。

No , this is not a bug.,这不是错误。

Divider is used to take the full width, just like any other view with the fillMaxWidth() modifier. Divider用于占据整个宽度,就像任何其他带有fillMaxWidth()修饰符的视图一样。

But inside horizontalScroll this modifier is ignored because it is ambiguous: horizontalScroll wraps the size of the content, so the maxWidth constraint in this area is infinite.但是在horizontalScroll ntalScroll 内部这个修饰符被忽略了,因为它是有歧义的: horizontalScroll ntalScroll 包裹了内容的大小,所以这个区域的maxWidth约束是无限大的。

From fillMaxWidth documentation :来自fillMaxWidth 文档

If the incoming maximum width is Constraints.Infinity this modifier will have no effect.如果传入的最大宽度为Constraints.Infinity ,则此修饰符将无效。

I haven't found any documentation mentioning horizontalScroll effects Constraints , you can see maintainer's answer on the same issue , or you can test it by yourself like this:我没有找到任何文档提到 horizo horizontalScroll effects Constraints ,你可以看到 maintainer's answer on the same issue ,或者你可以这样自己测试:

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

In this case you need to specify the width explicitly, eg:在这种情况下,您需要明确指定宽度,例如:

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

Note that when the top part of your LazyColumn is smaller than the bottom one, as in my example, the width will be smaller at first (to accommodate only the visible part), but after scrolling down and back up, the width will not be restored to its original width because the Divider width modifier will not let it shrink back down.请注意,当您的LazyColumn的顶部小于底部时,如在我的示例中,宽度首先会更小(以仅容纳可见部分),但向下滚动并返回后,宽度将不会是恢复到原来的宽度,因为Divider宽度修改器不会让它缩小。 If you need to prevent this, you need to calculate the `width' based only on the visible elements, which is more complicated.如果你需要防止这种情况,你需要只根据可见元素计算'宽度',这更复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM