@@ -19,38 +19,121 @@ package androidx.navigation.compose
1919import androidx.compose.animation.AnimatedContentTransitionScope
2020import androidx.compose.animation.EnterTransition
2121import androidx.compose.animation.ExitTransition
22+ import androidx.compose.animation.ExperimentalAnimationApi
2223import androidx.compose.animation.SizeTransform
24+ import androidx.compose.animation.core.CubicBezierEasing
25+ import androidx.compose.animation.core.LinearEasing
26+ import androidx.compose.animation.core.tween
27+ import androidx.compose.animation.unveilIn
28+ import androidx.compose.animation.veilOut
2329import androidx.navigation.NavBackStackEntry
24- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions
25- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions.enterTransition
26- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions.exitTransition
27- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions.predictivePopEnterTransition
28- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions.predictivePopExitTransition
29- import androidx.navigation.compose.internal.NonAndroidDefaultNavTransitions.sizeTransform
30-
31- // TODO: https://youtrack.jetbrains.com/issue/CMP-9920/Correctly-implement-DefaultNavTransitions-predictive-pop-transitions-for-iOS
30+ import androidx.navigationevent.NavigationEvent.Companion.EDGE_LEFT
31+
32+ private const val DEFAULT_TRANSITION_DURATION_MILLISECOND = 500
33+ private val IosTransitionEasing = CubicBezierEasing (0.2833f , 0.99f , 0.31833f , 0.99f )
34+
35+ @OptIn(ExperimentalAnimationApi ::class )
3236public actual object DefaultNavTransitions {
33- public actual val enterTransition: AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition
34- get() = NonAndroidDefaultNavTransitions .enterTransition
37+ public actual val enterTransition:
38+ AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition = {
39+ slideIntoContainer(
40+ towards = AnimatedContentTransitionScope .SlideDirection .Start ,
41+ animationSpec = tween(
42+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
43+ easing = IosTransitionEasing
44+ ),
45+ )
46+ }
3547
36- public actual val exitTransition: AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition
37- get() = NonAndroidDefaultNavTransitions .exitTransition
48+ public actual val exitTransition:
49+ AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition = {
50+ slideOutOfContainer(
51+ towards = AnimatedContentTransitionScope .SlideDirection .Start ,
52+ targetOffset = { it / 4 },
53+ animationSpec = tween(
54+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
55+ easing = IosTransitionEasing
56+ ),
57+ ) + veilOut(
58+ animationSpec = tween(
59+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
60+ easing = IosTransitionEasing
61+ ),
62+ )
63+ }
3864
3965 public actual val predictivePopEnterTransition:
40- AnimatedContentTransitionScope <NavBackStackEntry >.(Int ) -> EnterTransition
41- get() = NonAndroidDefaultNavTransitions .predictivePopEnterTransition
66+ AnimatedContentTransitionScope <NavBackStackEntry >.(Int ) -> EnterTransition =
67+ { edge ->
68+ val towards = if (edge == EDGE_LEFT ) {
69+ AnimatedContentTransitionScope .SlideDirection .Right
70+ } else {
71+ AnimatedContentTransitionScope .SlideDirection .Left
72+ }
73+ slideIntoContainer(
74+ towards = towards,
75+ initialOffset = { it / 4 },
76+ animationSpec = tween(
77+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
78+ easing = LinearEasing
79+ ),
80+ ) + unveilIn(
81+ animationSpec = tween(
82+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
83+ easing = LinearEasing
84+ ),
85+ )
86+ }
4287
4388 public actual val predictivePopExitTransition:
44- AnimatedContentTransitionScope <NavBackStackEntry >.(Int ) -> ExitTransition
45- get() = NonAndroidDefaultNavTransitions .predictivePopExitTransition
89+ AnimatedContentTransitionScope <NavBackStackEntry >.(Int ) -> ExitTransition =
90+ { edge ->
91+ val towards = if (edge == EDGE_LEFT ) {
92+ AnimatedContentTransitionScope .SlideDirection .Right
93+ } else {
94+ AnimatedContentTransitionScope .SlideDirection .Left
95+ }
96+ slideOutOfContainer(
97+ towards = towards,
98+ animationSpec = tween(
99+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
100+ easing = LinearEasing
101+ ),
102+ )
103+ }
46104
47105
48- public actual val sizeTransform: (AnimatedContentTransitionScope <NavBackStackEntry >.() -> SizeTransform ? )?
49- get() = NonAndroidDefaultNavTransitions .sizeTransform
106+ public actual val sizeTransform:
107+ (AnimatedContentTransitionScope <NavBackStackEntry >.() -> SizeTransform ? )? =
108+ null
50109
51- public actual fun popEnterTransition (enterTransition : AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition ): AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition =
52- NonAndroidDefaultNavTransitions .popEnterTransition(enterTransition)
110+ public actual fun popEnterTransition (
111+ enterTransition : AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition
112+ ): AnimatedContentTransitionScope <NavBackStackEntry >.() -> EnterTransition = {
113+ slideIntoContainer(
114+ towards = AnimatedContentTransitionScope .SlideDirection .End ,
115+ initialOffset = { it / 4 },
116+ animationSpec = tween(
117+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
118+ easing = IosTransitionEasing
119+ ),
120+ ) + unveilIn(
121+ animationSpec = tween(
122+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
123+ easing = IosTransitionEasing
124+ )
125+ )
126+ }
53127
54- public actual fun popExitTransition (exitTransition : AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition ): AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition =
55- NonAndroidDefaultNavTransitions .popExitTransition(exitTransition)
128+ public actual fun popExitTransition (
129+ exitTransition : AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition
130+ ): AnimatedContentTransitionScope <NavBackStackEntry >.() -> ExitTransition = {
131+ slideOutOfContainer(
132+ towards = AnimatedContentTransitionScope .SlideDirection .End ,
133+ animationSpec = tween(
134+ DEFAULT_TRANSITION_DURATION_MILLISECOND ,
135+ easing = IosTransitionEasing
136+ ),
137+ )
138+ }
56139}
0 commit comments