Reputation: 2834
Problem - scrolling downward causes the bottom sheet to scroll rather than giving scroll priority to the LazyColumn (RecyclerView did not have this problem. It was wrapped by a NestedScrollView)
I've just introduced a Compose LazyColumn replacement of a Recycler inside of a CoordinatorLayout. The Coordinator (implemented as a bottom sheet) can itself scroll freely between peek and expanded states. My issue is when dragging the items area downward in the LazyColumn, the bottom sheet picks up the scrolling rather than the LazyColumn . If I scroll upward first and then downward (without releasing) on the LazyColumn, the scrolling is picked up by the LazyColumn and scrolling priority is given to the LazyColumn (expected behavior.)
BottomSheetFragment
|-CoordinatorLayout
|--ConstraintLayout (BottomSheetBehavior)
|---MyListFragment
|----ComposeView
|-----Theme
|------Surface
|-------Box
|--------LazyColumn
New to Compose, so I'm hoping someone can tell me how to approach correcting this new scroll behavior?
**Edit I'm getting part of the way to having this work by toggling the Coordinator's ^^ BottomSheetBehavior.isDragglable, but it does require that I release the drag rather than smoothly transitioning from the list scroll to the bottom sheet scroll - anyone suggest a fix?:
fun MyUi(listener:Listener) {
val listState = rememberLazyListState()
LaunchedEffect(listState) {
listState.interactionSource.interactions.collect {
//at the top of the list so allow sheet scrolling
listener.allowSheetDrag(listState.firstVisibleItemScrollOffset == 0)
}
}
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
Timber.i("NestedScrollConnection onPreScroll($available: Offset, $source: NestedScrollSource)")
return super.onPreScroll(available, source)
}
override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset {
Timber.i("NestedScrollConnection onPostScroll($consumed: Offset, $available: Offset, $source: NestedScrollSource)")
if (available.y > 0.0 && consumed.y == 0.0f) {
//scolling down up but we're already at the top - kick over to sheet scrolling
listener.allowSheetDrag(true)
}
return super.onPostScroll(consumed, available, source)
}
}
}
Box(
modifier = Modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection)
) {
LazyColumn(
modifier =
Modifier
.fillMaxSize()
.padding(vertical = 12.dp), state = listState
) {
item {
Row() {}
}
}
}
}
And then in the Fragment:
override fun allowSheetDrag(allowSheetDrag: Boolean) {
bottomSheetFragment?.bottomSheetBehavior?.isDraggable = allowSheetDrag
}
Upvotes: 17
Views: 16694
Reputation: 2468
Wizard Chris Banes just recently published a workaround, which I can confirm it works.
It also transitions nicely without lifting a finger, when being used inside a BottomSheetDialog
(scrolling up, then dragging the sheet down in one go)
Example Usage (taken from Chris Banes' example):
setContent {
Surface(
// Add this somewhere near the top of your layout, above any scrolling layouts
modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
) {
LazyColumn() {
// blah
}
}
}
There is an issue being tracked for nested scrolling with ComposeViews: https://issuetracker.google.com/issues/174348612, and a related SO question which lead me there: AndroidView in Compose loses touch events in NestedScrollView
Upvotes: 28
Reputation: 383
Unfortunately, the interop for scrollability between XML and Compose is not great. There is a method on View called isNestedScrollingEnabled(), and Compose always returns false, so nested scrolling has unpredictable behaviors (which I believe you're describing here).
The way around it that I have found is to ensure that for content that can scroll larger than the full screen, you're placing your BottomSheet in a BottomSheetScaffold or other custom Composable view. As it stands, you will probably need to convert the whole experience to Compose before it will work in the way we would expect.
Compose is always evolving, as well. These comments are accurate for Compose 1.0.4 and Material Design library 1.3.0- it might change in the future.
Upvotes: 6