Optimize navigation transition (#45, #167, #178)

This commit is contained in:
BinTianqi
2025-10-24 13:21:59 +08:00
parent 6b6884911d
commit fccac11118
4 changed files with 59 additions and 58 deletions

View File

@@ -44,6 +44,10 @@ android {
debug { debug {
signingConfig = signingConfigs.getByName("defaultSignature") signingConfig = signingConfigs.getByName("defaultSignature")
} }
create("fastDebug") {
initWith(getByName("debug"))
isDebuggable = false
}
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_21

View File

@@ -228,7 +228,7 @@ import com.bintianqi.owndroid.dpm.WorkModesScreen
import com.bintianqi.owndroid.dpm.WorkProfile import com.bintianqi.owndroid.dpm.WorkProfile
import com.bintianqi.owndroid.dpm.WorkProfileScreen import com.bintianqi.owndroid.dpm.WorkProfileScreen
import com.bintianqi.owndroid.dpm.dhizukuErrorStatus import com.bintianqi.owndroid.dpm.dhizukuErrorStatus
import com.bintianqi.owndroid.ui.Animations import com.bintianqi.owndroid.ui.NavTransition
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import java.util.Locale import java.util.Locale
@@ -275,7 +275,11 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
val lifecycleOwner = LocalLifecycleOwner.current val lifecycleOwner = LocalLifecycleOwner.current
fun navigateUp() { navController.navigateUp() } fun navigateUp() { navController.navigateUp() }
fun navigate(destination: Any) { navController.navigate(destination) } fun navigate(destination: Any) {
navController.navigate(destination) {
launchSingleTop = true
}
}
fun choosePackage() { fun choosePackage() {
navController.navigate(ApplicationsList(false)) navController.navigate(ApplicationsList(false))
} }
@@ -293,10 +297,10 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
.fillMaxSize() .fillMaxSize()
.background(colorScheme.background) .background(colorScheme.background)
.pointerInput(Unit) { detectTapGestures(onTap = { focusMgr.clearFocus() }) }, .pointerInput(Unit) { detectTapGestures(onTap = { focusMgr.clearFocus() }) },
enterTransition = Animations.navHostEnterTransition, enterTransition = { NavTransition.enterTransition },
exitTransition = Animations.navHostExitTransition, exitTransition = { NavTransition.exitTransition },
popEnterTransition = Animations.navHostPopEnterTransition, popEnterTransition = { NavTransition.popEnterTransition },
popExitTransition = Animations.navHostPopExitTransition popExitTransition = { NavTransition.popExitTransition }
) { ) {
composable<Home> { HomeScreen(::navigate) } composable<Home> { HomeScreen(::navigate) }
composable<WorkModes> { composable<WorkModes> {

View File

@@ -1,52 +0,0 @@
package com.bintianqi.owndroid.ui
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.ui.unit.IntOffset
import androidx.navigation.NavBackStackEntry
object Animations {
private const val INITIAL_OFFSET_VALUE = 96
private const val TARGET_OFFSET_VALUE = 96
private val bezier = CubicBezierEasing(0.20f, 0.85f, 0.0f, 1f)
private val tween: FiniteAnimationSpec<IntOffset> = tween(durationMillis = 550, easing = bezier, delayMillis = 50)
val navHostEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
fadeIn(tween(100, easing = LinearEasing)) +
slideIntoContainer(
animationSpec = tween,
towards = AnimatedContentTransitionScope.SlideDirection.End,
initialOffset = { INITIAL_OFFSET_VALUE }
)
}
val navHostExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
fadeOut(tween(100, easing = LinearEasing)) +
slideOutOfContainer(
animationSpec = tween,
towards = AnimatedContentTransitionScope.SlideDirection.Start,
targetOffset = { -TARGET_OFFSET_VALUE }
)
}
val navHostPopEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
fadeIn(tween(100, easing = LinearEasing)) +
slideIntoContainer(
animationSpec = tween,
towards = AnimatedContentTransitionScope.SlideDirection.End,
initialOffset = { -INITIAL_OFFSET_VALUE }
)
}
val navHostPopExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
fadeOut(tween(100, easing = LinearEasing)) +
slideOutOfContainer(
animationSpec = tween,
towards = AnimatedContentTransitionScope.SlideDirection.Start,
targetOffset = { TARGET_OFFSET_VALUE }
)
}
}

View File

@@ -0,0 +1,45 @@
package com.bintianqi.owndroid.ui
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
/**
* Learned from AOSP's Activity animation
* `frameworks/base/core/res/res/anim/activity_xxx_xxx.xml`
*/
object NavTransition {
val StandardAccelerateEasing = CubicBezierEasing(0.3F, 0F, 1F, 1F)
val enterTransition: EnterTransition = slideInHorizontally(
tween(450, easing = FastOutSlowInEasing),
{ 96 }
) + fadeIn(
tween(83, 50, LinearEasing)
)
val exitTransition: ExitTransition = slideOutHorizontally(
tween(450, easing = StandardAccelerateEasing),
{ -96 }
) + fadeOut(tween(100, 200, LinearEasing))
val popEnterTransition: EnterTransition = slideInHorizontally(
tween(450, easing = FastOutSlowInEasing),
{ -96 }
)
val popExitTransition: ExitTransition =
slideOutHorizontally(
tween(450, easing = FastOutSlowInEasing),
{ 96 }
) + fadeOut(
tween(83, 35, LinearEasing)
)
}