android 通过ComposeView互操作在CoordinatorLayout内编写LazyColumn滚动行为

tquggr8v  于 2022-11-20  发布在  Android
关注(0)|答案(2)|浏览(106)

问题-向下滚动会导致底部工作表滚动,而不是将滚动优先级给予LazyColumn(RecyclerView没有此问题。它由NestedScrollView Package )
我刚刚介绍了一个Compose LazyColumn来替换CoordinatorLayout中的回收器。(实现为底部工作表)本身可以在查看和展开状态之间自由滚动。我的问题是,当在LazyColumn中向下拖动项区域时,底部工作表会拾取滚动,而不是LazyColumn。如果我先向上滚动,然后再向下滚动(未释放),滚动将由LazyColumn拾取,并将滚动优先级赋予LazyColumn(预期行为)。

BottomSheetFragment
|-CoordinatorLayout
|--ConstraintLayout (BottomSheetBehavior)
|---MyListFragment
|----ComposeView
|-----Theme
|------Surface
|-------Box
|--------LazyColumn

新的组成,所以我希望有人可以告诉我如何处理纠正这种新的滚动行为?

****编辑**我通过切换Coordinator的^^ 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
}
6qqygrtg

6qqygrtg1#

巫师克里斯·巴内斯最近刚刚发布了一个变通方案,我可以确认它的工作原理。
当在BottomSheetDialog中使用时(向上滚动,然后向下拖动工作表),它也可以很好地过渡,而无需抬起手指。

示例用法(摘自Chris巴内斯的示例):

setContent {
    Surface(
        // Add this somewhere near the top of your layout, above any scrolling layouts
        modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
    ) {
        LazyColumn() {
            // blah
        }
    }
}

使用合成视图跟踪嵌套滚动时存在问题:https://issuetracker.google.com/issues/174348612,以及一个相关的SO问题,它将我引导到这里:AndroidView in Compose loses touch events in NestedScrollView

u7up0aaq

u7up0aaq2#

不幸的是,XML和Compose之间的可滚动性互操作性不是很好。View上有一个名为isNestedScrollingEnabled()的方法,而Compose总是返回false,因此嵌套滚动具有不可预测的行为(我相信您在这里描述了这一点)。
我发现的解决方法是确保对于滚动范围大于全屏的内容,您将BottomSheet放置在BottomSheetScaffold或其他自定义Composable视图中。按照目前的情况,您可能需要将整个体验转换为Composes,然后它才能以我们预期的方式工作。
合成也一直在发展。这些评论对合成1.0.4和材料设计库1.3.0是准确的-它可能会在未来改变。

相关问题