how do you consume scroll events on the way down t...
# compose
g
how do you consume scroll events on the way down the composable hierarchy? If I add a
scrollable
modifier a parent composable, I never get the opportunity to consume scroll events before my children do. Basically i want to intercept the scroll gesture
1
j
cc @Shep Shapard
a
If you're willing to get into the guts of this a bit as it's changing, compose's input processing has three phases:
Initial
,
Main
and
Final
.
Initial
and
Main
roughly map to the onInterceptTouchEvent/onTouchEvent down-from-parent and up-from-child stages you're familiar with from views
We're currently moving to a suspend-based model of expressing gesture detection state machines, see
Modifier.pointerInput {}
- there's a DSL there that will let you install pointer event handlers and receive events at each of those pipeline stages, and at each phase you can consume motion from the event such that later processors (i.e. children in the
Initial
pass) will see it as consumed
You can also use the existing
PointerInputFilter
API for this; same mechanism either way
g
thanks Adam, i’ll take a look into these APIs what are your thoughts on including a hook for intercepting scroll in
ScrollableController
? it’d be nice to just say how many pixels i want to consume in the initial phase vs. the main phase without having to process all the complexities of a gesture myself
l
Do you have an example using the
pointerInput {}
modifier? I tried to use it the other day but using a
while (true)
sounded weird to me (maybe it's supposed to be used like that?)
a
I think the suspending input direction is going to give an even nicer way of expressing that than hooks in
ScrollableController
would
https://android-review.googlesource.com/c/platform/frameworks/support/+/1483931 gives a bit of an idea as to where we're going with this
😍 2
g
ok yeah i agree, this looks great. i might hold off on my component til this is merged, it looks like it makes my use case really easy
actually i lie, all of these drag extensions are happening in the main phase. it looks like there’s still no way (aside from writing everything myself) to consume events from the initial phase? would you consider making this possible as a part of this PR?
a
Can you describe the specific interaction you're building?
g
I am basically trying to think about how to build our collapsing header component (similar to the material one). I was thinking it could be a layout component with two child composables (a header and body). The component would basically: • consume upwards scroll events until the header is fully collapsed during the
Initial
phase. • consume downwards scrolls in the
Main
phase until the header is expanded again.
do you think that’s a legitimate use case, or am I way off with my impl idea here?
a
It's one approach but the nested scrolling use cases are still WIP. @matvei
👍 1
m
Yup, working on this. Seems like this usecase fits the explorations we've done so far, stay tuned 🙂
🙌 1
📺 1
g
thanks both!
a
A challenge is that scrolling is often a composite of motion from many pointers or sources. Knowing how much motion to consume from each pointer in those cases to achieve a result isn't always clear
Which is part of why nested scrolling is a separate, higher level concept in Android views
g
yeah, if I’m honest i’m never really that clear on how I should handle additional pointers, i usually ignore them in my custom touch logic 🙈
a
Many do 🙂 we're trying to make that easier/more automatic with some of the APIs described above
🙌 1