当放置在具有 horizontalScroll 修饰符集的可组合项内时,分隔符可组合项变得不可见。这是一个错误吗?
Divider composable becomes invisible when placed inside composable with horizontalScroll modifier set. Is this a bug?
背景
我正在制作桌面撰写应用程序。
我有一个 LazyColumn
和 Divider
分隔项。 LazyColumn
的宽度可能不适合 window,所以我通过将 LazyColumn
封装在 Box
中并设置了 horizontalScroll()
修饰符,使 LazyColumn
可以水平滚动。
现在 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"
我想知道这是否是一个错误?或者有什么办法可以解决这个问题。
否,这不是错误。
Divider
用于占满宽度,就像使用 fillMaxWidth()
修饰符的任何其他视图一样。
但是在horizontalScroll
里面这个修饰符被忽略了,因为它是有歧义的:horizontalScroll
包裹了内容的大小,所以maxWidth
这个区域的约束是无限的。
来自 fillMaxWidth
documentation:
If the incoming maximum width is Constraints.Infinity
this modifier will have no effect.
我没有找到任何文档提到horizontalScroll
影响Constraints
,你可以在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}")
}
}
在这种情况下,您需要明确指定宽度,例如:
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
宽度修饰符不会让它缩小。如果需要防止这种情况,需要只根据可见元素计算'width',比较复杂。
背景
我正在制作桌面撰写应用程序。
我有一个 LazyColumn
和 Divider
分隔项。 LazyColumn
的宽度可能不适合 window,所以我通过将 LazyColumn
封装在 Box
中并设置了 horizontalScroll()
修饰符,使 LazyColumn
可以水平滚动。
现在 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"
我想知道这是否是一个错误?或者有什么办法可以解决这个问题。
否,这不是错误。
Divider
用于占满宽度,就像使用 fillMaxWidth()
修饰符的任何其他视图一样。
但是在horizontalScroll
里面这个修饰符被忽略了,因为它是有歧义的:horizontalScroll
包裹了内容的大小,所以maxWidth
这个区域的约束是无限的。
来自 fillMaxWidth
documentation:
If the incoming maximum width is
Constraints.Infinity
this modifier will have no effect.
我没有找到任何文档提到horizontalScroll
影响Constraints
,你可以在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}")
}
}
在这种情况下,您需要明确指定宽度,例如:
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
宽度修饰符不会让它缩小。如果需要防止这种情况,需要只根据可见元素计算'width',比较复杂。