adjpd
09/22/2021, 10:42 PMModifier.scrollable
and Modifier.horizontalScroll
clip their children differently. Is this a bug? Code in 🧵.Box(
Modifier
.size(70.dp)
.scrollable(
orientation = Orientation.Horizontal,
state = rememberScrollableState { it }
)
) {
Box(
Modifier
.size(200.dp)
.border(10.dp, Color.Green)
.background(Color.Red)
)
}
horizontalScroll
version. This is the second image.
Box(
Modifier
.size(70.dp)
.horizontalScroll(rememberScrollState())
) {
Box(
Modifier
.size(200.dp)
.border(10.dp, Color.Green)
.background(Color.Red)
)
}
Modifier.scrollable
to move the offset of the child, the full 200.dp
isn't there. It's been cut.Ian Lake
09/22/2021, 10:49 PMorientation = Orientation.Vertical,
in your scrollable
code? That would be vertically scrolling, not horizontal scrollingadjpd
09/22/2021, 10:49 PMhorizontalScroll
. See below.
Shouldn't Modifier.scrollable
do something similar?
I can't do it from my own code, easily, since clipScrollableContainer
is private in the compose libs.
val layout = ScrollingLayoutModifier(state, reverseScrolling, isVertical)
semantics.then(scrolling).clipScrollableContainer(isVertical).then(layout)
Modifier.scrollable
to scroll a child that's bigger than its parent.
https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]eSamples.kt;l=57;drc=5f80de6c0af73c334fbd8702e5e5745844fb42b0
Surely this a bug?Albert Chang
09/23/2021, 1:00 AMModifier.scrollable()
is a relatively low-level API that you can use to create your own scrollable component. The difference is not caused by how they clip their children. It's because Modifier.scrollable()
doesn't automatically measure its children with infinite max width, which Modifier.horizontalScroll()
does.adjpd
09/23/2021, 1:12 AMscrollable
to mesaure its children as so. Currently this mean scrollable
without extra code doesn't scroll the child. And that seems rather un-intuitive. It, at least, should be explained and documented.Albert Chang
09/23/2021, 1:16 AMModifier.horizontalScroll()
?
Modifier.scrollable()
is always used with custom layout since you need to specify the scrolling logic yourself. Something like:
Layout(
content = { /*TODO*/ },
modifier = Modifier.scrollable(...)
) { measurables, constraints ->
val childrenConstraints = constraints.copy(maxWidth = Constraints.Infinity)
val placeables = measurables.fastMap { it.measure(childrenConstraints) }
layout(constraints.maxWidth, constraints.maxHeight) {
placeables.fastForEach { it.place(0, 0) }
}
}
adjpd
09/23/2021, 8:50 AMscrollable
scrolls anything or at least tells you that you need to do more to scroll than just use the modifier.Albert Chang
09/23/2021, 9:04 AMUsers should update their state themselves using default [ScrollableState] and itsAnd "reflect their own state in UI" includes using the scroll offset to show different parts of the content. Basically if you just want to make a component scrollable, there's literally no reason to use this modifier. This modifier is for cases that the high-level APIs don't fit, where you usually have some custom layout logic anyway. For example, the Pager in accompanist used to use this modifier.callback or by implementing [ScrollableState] interface manually and reflect their own state in UI when using this component.consumeScrollDelta
adjpd
09/23/2021, 9:10 AM