Reputation: 63
Iam designing a Horizontal Pager in Android Jetpack Compose using googles accompanist Pager (implementation "com.google.accompanist:accompanist-pager:0.24.2-alpha"). I Implement this Horizontal Pager Correctly. But I want to change the default Animation of pager from horizontal left/ right swipe to fadein/ fadeout animation. Iam new to compose and i didn't find any useful resources in the internet. If anyone knows this help me to find the correct solutions. Thanks in Advance.
val pagerState = rememberPagerState()
HorizontalPager(count = 3, state = pagerState
) { pagePosition ->
PagerScreen(onBoardingData = onBoardingDataList[pagePosition])
}
Here PagerScreen is a composable function for each screen.
Like this Gif I want fadein / fadeout for horizontal Pager
Upvotes: 1
Views: 5022
Reputation: 15064
Solution using the recommended graphicsLayer
and HorizontalPager
:
val pagerState = rememberPagerState()
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxWidth()
) { page ->
val isRtl =
LocalContext.current.resources.configuration.layoutDirection == LayoutDirection.RTL
Item(
// ...
modifier = Modifier.graphicsLayer {
val pageOffset =
((pagerState.currentPage - page) + pagerState.currentPageOffsetFraction)
alpha = lerp(
start = 0f,
stop = 1f,
fraction = 1f - pageOffset.absoluteValue.coerceIn(0f, 1f),
)
val fraction =
if (pagerState.currentPage != page) -pageOffset else 1f - pageOffset
translationX = lerp(
start = size.width,
stop = 0f,
fraction = if (isRtl) 2f - fraction else fraction,
)
}
)
}
Upvotes: 2
Reputation: 23964
I'm not sure if there's a better solution using the HorizontalPager
, so I did this solution using swipeable
modifier.
@ExperimentalMaterialApi
@Composable
fun SwipeableSampleScreen5() {
val pages = listOf(
596 to Color(203, 41, 61),
801 to Color(107, 0, 141),
492 to Color(40, 38, 149),
718 to Color(56, 144, 244),
550 to Color(60, 149, 159)
)
val swipeableState = rememberSwipeableState(0)
// This Box is only to get the screen's width
BoxWithConstraints(Modifier.fillMaxWidth()) {
val widthPx = with(LocalDensity.current) {
maxWidth.toPx()
}
// Each anchor of the swipeable is the index * screen width
val anchors = remember(pages) {
List(pages.size) { index ->
-(index * widthPx) to index
}.toMap()
}
// This Box is capturing the swipe gesture
Box(
modifier = Modifier
.fillMaxSize()
.swipeable(
state = swipeableState,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.5f) },
orientation = Orientation.Horizontal,
)
) {
// swipeableState provides the current index and the next index
val currentIndex = swipeableState.currentValue
val nextIndex = swipeableState.progress.to
// This Box is behind and will display the nextValue
Box(
Modifier
// graphicsLayer is applied to the content
.graphicsLayer {
alpha = 1f
},
) {
Box(
Modifier
.fillMaxSize()
.background(pages[nextIndex].second),
contentAlignment = Alignment.Center
) {
Text(
text = pages[nextIndex].first.toString(),
style = MaterialTheme.typography.h1.copy(color = Color.White),
)
}
}
// This Box is showing the current value which will change
// the alpha during the swiping
Box(
Modifier
.graphicsLayer {
alpha = 1f - swipeableState.progress.fraction
},
) {
Box(
Modifier
.fillMaxSize()
.background(pages[currentIndex].second),
contentAlignment = Alignment.Center
) {
Text(
text = pages[currentIndex].first.toString(),
style = MaterialTheme.typography.h1.copy(color = Color.White),
)
}
}
}
}
}
The solution is commented, but for a better understanding this article helped me a lot.
Here's the result:
You can find the full source here.
Upvotes: 0