From 04b06f59463aa246399271b2cc56a8553616aa59 Mon Sep 17 00:00:00 2001 From: Yang Date: Wed, 6 Dec 2023 22:10:22 +1100 Subject: [PATCH] Pager scale transition effect. --- .../kstreamlined/android/KSActivity.kt | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/java/io/github/reactivecircus/kstreamlined/android/KSActivity.kt b/android/app/src/main/java/io/github/reactivecircus/kstreamlined/android/KSActivity.kt index f3a4bb88..75c03d08 100644 --- a/android/app/src/main/java/io/github/reactivecircus/kstreamlined/android/KSActivity.kt +++ b/android/app/src/main/java/io/github/reactivecircus/kstreamlined/android/KSActivity.kt @@ -4,13 +4,17 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.compose.animation.core.EaseInOutQuart +import androidx.compose.animation.core.tween import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -19,8 +23,10 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.lerp import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import dagger.hilt.android.AndroidEntryPoint import io.github.reactivecircus.kstreamlined.android.designsystem.component.NavigationIsland @@ -32,6 +38,7 @@ import io.github.reactivecircus.kstreamlined.android.designsystem.foundation.ico import io.github.reactivecircus.kstreamlined.android.designsystem.foundation.icon.Kotlin import io.github.reactivecircus.kstreamlined.android.feature.home.HomeScreen import io.github.reactivecircus.kstreamlined.android.feature.savedforlater.SavedForLaterScreen +import kotlin.math.absoluteValue @AndroidEntryPoint class KSActivity : ComponentActivity() { @@ -52,7 +59,11 @@ class KSActivity : ComponentActivity() { window.navigationBarColor = navigationBarColor } - Box(modifier = Modifier.fillMaxSize()) { + Box( + modifier = Modifier + .fillMaxSize() + .background(KSTheme.colorScheme.background) + ) { var selectedNavItem by rememberSaveable { mutableStateOf(NavItemKey.Home) } val pagerState = rememberPagerState(pageCount = { NavItemKey.entries.size }) @@ -64,16 +75,27 @@ class KSActivity : ComponentActivity() { ) { when (it) { NavItemKey.Home.ordinal -> { - HomeScreen() + HomeScreen( + modifier = Modifier.pagerScaleTransition(it, pagerState) + ) } + NavItemKey.Saved.ordinal -> { - SavedForLaterScreen() + SavedForLaterScreen( + modifier = Modifier.pagerScaleTransition(it, pagerState) + ) } } } LaunchedEffect(selectedNavItem) { - pagerState.animateScrollToPage(selectedNavItem.ordinal) + pagerState.animateScrollToPage( + page = selectedNavItem.ordinal, + animationSpec = tween( + durationMillis = 400, + easing = EaseInOutQuart, + ), + ) } NavigationIsland( @@ -106,6 +128,19 @@ class KSActivity : ComponentActivity() { } } +@OptIn(ExperimentalFoundationApi::class) +private fun Modifier.pagerScaleTransition(page: Int, pagerState: PagerState) = graphicsLayer { + val pageOffset = (pagerState.currentPage - page) + pagerState.currentPageOffsetFraction + lerp( + start = 0.8f, + stop = 1f, + fraction = 1f - pageOffset.absoluteValue.coerceIn(0f, 1f), + ).also { scale -> + scaleX = scale + scaleY = scale + } +} + enum class NavItemKey { Home, Saved,