I want that during a right swipe, the first element disappears and the lower card (child) appears on top, essentially using a fade-out and zoom-in animation
My code. Looks like my animation's code works incorrectly
val pagerState = rememberPagerState(initialPage = 0) {
pagerCount
}
Box(modifier = modifier) {
for (i in 0 until pagerCount - 1) {
Column(
modifier = Modifier
.padding(
top = Spaces.xs2 * (pagerCount - i),
start = Spaces.xs2 * (pagerCount - i),
end = Spaces.xs2 * (pagerCount - i),
)
) {
item(i.toFloat())
if (i == 1) {
button(Spaces.xs2 * (pagerCount - i))
}
}
HorizontalPager(
modifier = modifier,
state = pagerState,
) { page ->
Box(
modifier = Modifier
.graphicsLayer {
val pageOffset = pagerState.offsetForPage(page)
val scale = 1f - abs(pageOffset) * 0.2f
scaleX = scale
scaleY = scale
alpha = 1f - abs(pageOffset)
}
) {
item(page.toFloat())
}
}
}
}
}
private fun PagerState.offsetForPage(page: Int): Float {
return this.currentPageOffsetFraction + (page - this.currentPage)
}
I am not sure what exactly you want to achieve, but the closest thing to what you are describing that can be achieved using HorizontalPager
is like this:
@Composable
fun SpecialPager() {
val pagerCount = 5
val pagerState = rememberPagerState(initialPage = 0) {
pagerCount
}
HorizontalPager(
state = pagerState,
) { page ->
Column(
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
// Calculate the absolute offset for the current page from the
// scroll position. We use the absolute value which allows us to mirror
// any effects for both directions
val pageOffset = (pagerState.currentPage - page + pagerState.currentPageOffsetFraction).absoluteValue
// We animate the alpha, between 50% and 100%
alpha = lerp(
start = 0.5f,
stop = 1f,
fraction = 1f - pageOffset.coerceIn(0f, 1f)
)
scaleX = lerp(
start = 0.5f,
stop = 1f,
fraction = 1f - pageOffset.coerceIn(0f, 1f)
)
scaleY = lerp(
start = 0.5f,
stop = 1f,
fraction = 1f - pageOffset.coerceIn(0f, 1f)
)
},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Card(
modifier = Modifier
.width(300.dp)
.heightIn(600.dp)
) {
// some Composable
}
}
}
}
Output:
If you really want a stack, meaning that the old cards don't slide out of the screen, and the new cards slide in on the top, then I think you cannot achieve this using a HorizontalPager. HorizontalPager
uses a lazy list under the hood, and a new item only can enter the screen when the old one scrolls out of the viewport.