diff --git a/manager/app/build.gradle.kts b/manager/app/build.gradle.kts index 1f98e4a1ba62..ce7cf2f1e826 100644 --- a/manager/app/build.gradle.kts +++ b/manager/app/build.gradle.kts @@ -92,6 +92,10 @@ android { } } +ksp { + arg("compose-destinations.defaultTransitions", "none") +} + dependencies { implementation(libs.androidx.activity.compose) implementation(libs.androidx.navigation.compose) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt index 5737c524a940..6db05aa6c216 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt @@ -11,6 +11,9 @@ import androidx.compose.animation.ExitTransition import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleOut +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.displayCutout @@ -59,13 +62,16 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) - val isManager = Natives.becomeManager(ksuApp.packageName) - if (isManager) install() + val isManager = Natives.becomeManager(ksuApp.packageName) + if (isManager) install() setContent { KernelSUTheme { val navController = rememberNavController() val snackBarHostState = remember { SnackbarHostState() } + val bottomBarRoutes = remember { + BottomBarDestination.entries.map { it.direction.route }.toSet() + } Scaffold( bottomBar = { BottomBar(navController) }, contentWindowInsets = WindowInsets(0, 0, 0, 0) @@ -78,10 +84,45 @@ class MainActivity : ComponentActivity() { navGraph = NavGraphs.root, navController = navController, defaultTransitions = object : NavHostAnimatedDestinationStyle() { - override val enterTransition: AnimatedContentTransitionScope.() -> EnterTransition - get() = { fadeIn(animationSpec = tween(340)) } - override val exitTransition: AnimatedContentTransitionScope.() -> ExitTransition - get() = { fadeOut(animationSpec = tween(340)) } + override val enterTransition: AnimatedContentTransitionScope.() -> EnterTransition = { + // If the target is a detail page (not a bottom navigation page), slide in from the right + if (targetState.destination.route !in bottomBarRoutes) { + slideInHorizontally(initialOffsetX = { it }) + } else { + // Otherwise (switching between bottom navigation pages), use fade in + fadeIn(animationSpec = tween(340)) + } + } + + override val exitTransition: AnimatedContentTransitionScope.() -> ExitTransition = { + // If navigating from the home page (bottom navigation page) to a detail page, slide out to the left + if (initialState.destination.route in bottomBarRoutes && targetState.destination.route !in bottomBarRoutes) { + slideOutHorizontally(targetOffsetX = { -it / 4 }) + fadeOut() + } else { + // Otherwise (switching between bottom navigation pages), use fade out + fadeOut(animationSpec = tween(340)) + } + } + + override val popEnterTransition: AnimatedContentTransitionScope.() -> EnterTransition = { + // If returning to the home page (bottom navigation page), slide in from the left + if (targetState.destination.route in bottomBarRoutes) { + slideInHorizontally(initialOffsetX = { -it / 4 }) + fadeIn() + } else { + // Otherwise (e.g., returning between multiple detail pages), use default fade in + fadeIn(animationSpec = tween(340)) + } + } + + override val popExitTransition: AnimatedContentTransitionScope.() -> ExitTransition = { + // If returning from a detail page (not a bottom navigation page), scale down and fade out + if (initialState.destination.route !in bottomBarRoutes) { + scaleOut(targetScale = 0.9f) + fadeOut() + } else { + // Otherwise, use default fade out + fadeOut(animationSpec = tween(340)) + } + } } ) }