如何在 Horizo​​ntalPager 中设置偏移动画?

How to animate offset in HorizontalPager?

我在 Horizo​​ntalPager 中有三张卡片,我想在用户滚动页面时为其偏移设置动画 like this one

val pagerState = rememberPagerState(pageCount = 3)
val currentIndex = pagerState.currentPage
HorizontalPager(
        state = pagerState,
        modifier = Modifier.fillMaxSize()
    ) { page ->
        Card(
            modifier = Modifier
                .fillMaxWidth(0.7f)
                .fillMaxHeight(0.7f)
                .padding(22.dp)
                .offset(y = if (currentIndex == page) 0.dp else 70.dp),
            shape = RoundedCornerShape(30.dp),
            elevation = 110.dp
        ) {}
    }

您可以使用 pagerState.currentPageOffset 计算偏移量。

当您滚动 HorizontalPager 时,currentPage 将不会改变,直到您释放拖动。当你向右滚动时,currentPageOffset0f增加到1f,当你向左滚动时,它从0f减少到-1f

在我的代码中,我为每个页面计算 offset

  1. 当前页面的偏移量应该随着我们左右滚动而增加,所以我们可以取absoluteValue
  2. 只要 currentPageOffset0f 变为 -1f,左页偏移就应该减少。
  3. 右页偏移量应减少,而 currentPageOffset0f 增加到 1f
@Composable
fun TestScreen() {
    val pagerState = rememberPagerState(pageCount = 3)
    val currentIndex = pagerState.currentPage
    val currentPageOffset = pagerState.currentPageOffset
    HorizontalPager(
        state = pagerState,
        modifier = Modifier.fillMaxSize()
    ) { page ->
        val offset = maxOffset * when (page) {
            currentIndex -> {
                currentPageOffset.absoluteValue
            }
            currentIndex - 1 -> {
                1 + currentPageOffset.coerceAtMost(0f)
            }
            currentIndex + 1 -> {
                1 - currentPageOffset.coerceAtLeast(0f)
            }
            else -> {
                1f
            }
        }
        Card(
            modifier = Modifier
                .fillMaxWidth(0.7f)
                .fillMaxHeight(0.7f)
                .padding(22.dp)
                .offset(y = offset),
            shape = RoundedCornerShape(30.dp),
            elevation = 110.dp
        ) {}
    }
}

private val maxOffset = 70.dp

结果: