jch*_*tof 16 android vertical-scrolling android-jetpack-compose lazycolumn
问题 - 向下滚动会导致底部工作表滚动,而不是为 LazyColumn 提供滚动优先级(RecyclerView 没有此问题。它被 NestedScrollView 包裹)
我刚刚介绍了用 Compose LazyColumn 替换 CoordinatorLayout 内的 Recycler。协调器(作为底部工作表实现)本身可以在查看状态和展开状态之间自由滚动。我的问题是,当在 LazyColumn 中向下拖动项目区域时,底部工作表会滚动而不是 LazyColumn 。如果我在 LazyColumn 上先向上滚动,然后向下滚动(不释放),则 LazyColumn 会拾取滚动,并且滚动优先级将赋予 LazyColumn(预期行为)。
BottomSheetFragment
|-CoordinatorLayout
|--ConstraintLayout (BottomSheetBehavior)
|---MyListFragment
|----ComposeView
|-----Theme
|------Surface
|-------Box
|--------LazyColumn
刚接触 Compose,所以我希望有人能告诉我如何纠正这种新的滚动行为?
**编辑 我通过切换协调器的 ^^ BottomSheetBehavior.isDragglable 来完成这项工作,但它确实需要我释放拖动,而不是从列表滚动平滑过渡到底部工作表滚动 - 任何人建议修复?:
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() {}
            }
        }
    }
}
然后在片段中:
override fun allowSheetDrag(allowSheetDrag: Boolean) {
    bottomSheetFragment?.bottomSheetBehavior?.isDraggable = allowSheetDrag
}
Ste*_*nke 26
巫师克里斯·贝恩斯最近刚刚发布了一个解决方法,我可以确认它是有效的。
在内部使用时BottomSheetDialog(向上滚动,然后一次性向下拖动纸张),它也可以很好地过渡,而无需抬起手指
用法示例(取自 Chris Banes 的示例):
setContent {
    Surface(
        // Add this somewhere near the top of your layout, above any scrolling layouts
        modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
    ) {
        LazyColumn() {
            // blah
        }
    }
}
使用 ComposeViews 跟踪嵌套滚动时存在一个问题: https: //issuetracker.google.com/issues/174348612,以及一个相关的 SO 问题引导我到达那里:AndroidView in Compose Loss touch events in NestedScrollView
小智 6
不幸的是,XML 和 Compose 之间的可滚动性互操作性不是很好。View 上有一个名为 isNestedScrollingEnabled() 的方法,并且 Compose 始终返回 false,因此嵌套滚动具有不可预测的行为(我相信您在这里描述了这一点)。
我发现的解决方法是确保对于可以滚动大于全屏的内容,您将 BottomSheet 放置在 BottomSheetScaffold 或其他自定义可组合视图中。就目前情况而言,您可能需要将整个体验转换为 Compose,然后它才能按照我们期望的方式工作。
Compose 也总是在不断发展。这些注释对于 Compose 1.0.4 和 Material Design 库 1.3.0 来说是准确的 - 将来可能会发生变化。
| 归档时间: | 
 | 
| 查看次数: | 13044 次 | 
| 最近记录: |