I have three cards in HorizontalPager and I want to animate its offset like this one when user scroll through pages.
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
) {}
}
CodePudding user response:
You can calculate the offset using pagerState.currentPageOffset
.
When you scroll the HorizontalPager
, the currentPage
will not change until you release the drag. When you scroll to the right, currentPageOffset
increases from 0f
to 1f
, and when you scroll to the left, it decreases from 0f
to -1f
.
In my code, I calculate offset
for each page:
- The offset of the current page should increase as we scroll left and right, so we can take
absoluteValue
. - The left page offset should decrease as long as
currentPageOffset
changes from0f
to-1f
. - The right page offset should decrease while
currentPageOffset
increases from0f
to1f
.
@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
Result: