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
}
isDraggable
. Needed some extra tweakings for ironing out some edge cases while dragging, and am quite happy with the solution now. Basically observinglistState
s scrolling state in aLaunchedEffect
, and setting some flags depending on where you touch down (list or container). It still requires to lift the finger once, when dragging up, to continue dragging the sheet downwards, but I found out this is actually how other some sheets behave as well, so I consider it ok for my use case. Thanks again! – Selfabnegation