
想要的效果如下:
https://youtube.com/shorts/unI7ztB5EE4?si=dxGw2OFCGLy6dawp
有尝试使用 NestedScrollConnection 但没解决问题,外层的 VerticalPager 想要到下一页或者上一页,必须滑动很长的距离,体验很不好。想来是自己太菜了,特来求助各位大佬。另外有个疑问,我看文档描述,onPreScroll 方法返回值便是父级容器将要消耗的滚动量,但我直接返回 Offset(0.0f, available.y) 按理说应该子容器 Column 不会滚动,而是作为父容器的 VerticalPager 去消耗滚动量,进入下一页。但实际情况却是两个容器都不会出现滚动效果。
@OptIn(ExperimentalFoundationApi::class) @Composable fun NestedScrollExample(modifier: Modifier = Modifier) { val pageCount = 5 val pagerState = rememberPagerState(pageCount = { pageCount }) val scrollStates = List(pageCount) { rememberScrollState() } val nestedScrollCOnnection= remember { object : NestedScrollConnection { override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { val delta = available.y val page = pagerState.currentPage val scrollState = scrollStates[page] // only test the scroll down case // If the user scrolls down, and the column item of the current page has not scrolled to the bottom, let the child consume the scroll. if (delta < 0) { return if (scrollState.canScrollForward) Offset.Zero else Offset(0.0f, delta) } return super.onPreScroll(available, source) } } } VerticalPager( state = pagerState, modifier = modifier .nestedScroll(nestedScrollConnection) .fillMaxSize(), ) { page -> Column( modifier = Modifier .verticalScroll(scrollStates[page]) .fillMaxSize() ) { repeat(20) { Text("Page $page item $it", modifier = Modifier.padding(16.dp)) } } } } 1 murmurkerman 2024-09-06 19:07:44 +08:00 啊,这个不是好的么 |
2 murmurkerman 2024-09-06 19:20:30 +08:00 这个是好的,加上 key 来保留滚动位置 @Preview @OptIn(ExperimentalFoundationApi::class) @Composable fun VerticalPagerWithLazyColumn( modifier: Modifier = Modifier ) { val pagerState = rememberPagerState( pageCount = { 5 } ) VerticalPager( state = pagerState, key = { it }, modifier = modifier.fillMaxSize() ) { page -> Box { Column( modifier = Modifier .verticalScroll(rememberScrollState()) .fillMaxSize() ) { for (i in 0..20) { Text( "Item $i on page $page", modifier = Modifier.padding(30.dp) ) } } Text( "Page $page", modifier = Modifier .padding(16.dp) .align(Alignment.Center) ) } } } |
3 yl20181003 OP @murmurkerman 多谢大佬,我开机去试试 |
4 mxalbert1996 2024-09-07 00:47:39 +08:00 via Android 为什么要用自定义的 NestedScrollConnection ? Compose 的默认的 nested scroll 应该就是视频里的效果。 然后 onPreScroll 是返回**你**消耗的滚动量,不是说你返回一个数值 Compose 就自动帮你消耗了。你要自己消耗,比如通过 pagerState.dispatchRawDelta()。 |
5 yl20181003 OP @mxalbert1996 #4 `然后 onPreScroll 是返回**你**消耗的滚动量,不是说你返回一个数值 Compose 就自动帮你消耗了` 多谢提醒,这个我一直以为是交给 Compose 去消耗 ![]() |