菜鸡问个 Android Jetpack Compose 的问题,如何实现 VerticalPager 嵌套一个可滚动的 Cloumn

103 天前
 yl20181003

想要的效果如下:

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))
            }
        }
    }
}
3051 次点击
所在节点    Android
5 条回复
murmurkerman
102 天前
啊,这个不是好的么
murmurkerman
102 天前
这个是好的,加上 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)
)
}
}
}
yl20181003
102 天前
@murmurkerman 多谢大佬,我开机去试试 😂
mxalbert1996
102 天前
为什么要用自定义的 NestedScrollConnection ? Compose 的默认的 nested scroll 应该就是视频里的效果。
然后 onPreScroll 是返回**你**消耗的滚动量,不是说你返回一个数值 Compose 就自动帮你消耗了。你要自己消耗,比如通过 pagerState.dispatchRawDelta()。
yl20181003
100 天前
@mxalbert1996 #4 `然后 onPreScroll 是返回**你**消耗的滚动量,不是说你返回一个数值 Compose 就自动帮你消耗了` 多谢提醒,这个我一直以为是交给 Compose 去消耗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1070759

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX