diff --git a/lib/get_navigation/src/extension_navigation.dart b/lib/get_navigation/src/extension_navigation.dart index c12e2e5c7..ccf012836 100644 --- a/lib/get_navigation/src/extension_navigation.dart +++ b/lib/get_navigation/src/extension_navigation.dart @@ -495,6 +495,11 @@ extension GetNavigationExt on GetInterface { /// /// [id] is for when you are using nested navigation, /// as explained in documentation + /// + /// [oldPage] is the page widget that you want to replace with the new one + /// when you use a custom [transition], we need to change the old page exit transition, + /// otherwise it will show black container in some case, it fixes the bug: + /// https://github.com/jonataslaw/getx/issues/1560 /// /// If you want the same behavior of ios that pops a route when the user drag, /// you can set [popGesture] to true @@ -504,7 +509,8 @@ extension GetNavigationExt on GetInterface { /// By default, GetX will prevent you from push a route that you already in, /// if you want to push anyway, set [preventDuplicates] to false Future? to(Widget Function() page, - {bool? opaque, + {Widget? oldPage, + bool? opaque, Transition? transition, Curve? curve, Duration? duration, @@ -522,6 +528,7 @@ extension GetNavigationExt on GetInterface { PreventDuplicateHandlingMode.reorderRoutes}) { return searchDelegate(id).to( page, + oldPage: oldPage, opaque: opaque, transition: transition, curve: curve, diff --git a/lib/get_navigation/src/routes/default_transitions.dart b/lib/get_navigation/src/routes/default_transitions.dart index e6cad4a8c..e05495def 100644 --- a/lib/get_navigation/src/routes/default_transitions.dart +++ b/lib/get_navigation/src/routes/default_transitions.dart @@ -10,22 +10,26 @@ class LeftToRightFadeTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(-1.0, 0.0), - end: Offset.zero, - ).animate(animation), - child: FadeTransition( - opacity: animation, - child: SlideTransition( - position: Tween( - begin: Offset.zero, - end: const Offset(1.0, 0.0), - ).animate(secondaryAnimation), - child: child), - ), - ); + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) oldPage, + SlideTransition( + position: Tween( + begin: const Offset(-1.0, 0.0), + end: Offset.zero, + ).animate(animation), + child: FadeTransition( + opacity: animation, + child: SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(1.0, 0.0), + ).animate(secondaryAnimation), + child: child), + ), + ) + ]); } } @@ -36,22 +40,26 @@ class RightToLeftFadeTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(1.0, 0.0), - end: Offset.zero, - ).animate(animation), - child: FadeTransition( - opacity: animation, - child: SlideTransition( - position: Tween( - begin: Offset.zero, - end: const Offset(-1.0, 0.0), - ).animate(secondaryAnimation), - child: child), + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) oldPage, + SlideTransition( + position: Tween( + begin: const Offset(1.0, 0.0), + end: Offset.zero, + ).animate(animation), + child: FadeTransition( + opacity: animation, + child: SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(-1.0, 0.0), + ).animate(secondaryAnimation), + child: child), + ), ), - ); + ]); } } @@ -74,8 +82,16 @@ class FadeInTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return FadeTransition(opacity: animation, child: child); + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) + FadeTransition( + opacity: Tween(begin: 1, end: 0).animate(animation), + child: oldPage, + ), + FadeTransition(opacity: animation, child: child) + ]); } } @@ -86,14 +102,25 @@ class SlideDownTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(0.0, 1.0), - end: Offset.zero, - ).animate(animation), - child: child, - ); + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) + SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(0.0, -1.0), + ).animate(animation), + child: oldPage, + ), + SlideTransition( + position: Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, + ).animate(animation), + child: child, + ), + ]); } } @@ -104,13 +131,26 @@ class SlideLeftTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(-1.0, 0.0), - end: Offset.zero, - ).animate(animation), - child: child, + Widget child, + Widget? oldPage) { + return Stack( + children: [ + if (oldPage != null) + SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(1.0, 0.0), + ).animate(animation), + child: oldPage, + ), + SlideTransition( + position: Tween( + begin: const Offset(-1.0, 0.0), + end: Offset.zero, + ).animate(animation), + child: child, + ) + ], ); } } @@ -122,32 +162,55 @@ class SlideRightTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(1.0, 0.0), - end: Offset.zero, - ).animate(animation), - child: child, - ); + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) + SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(-1.0, 0.0), + ).animate(animation), + child: oldPage, + ), + SlideTransition( + position: Tween( + begin: const Offset(1.0, 0.0), + end: Offset.zero, + ).animate(animation), + child: child, + ), + ]); } } class SlideTopTransition { Widget buildTransitions( - BuildContext context, - Curve? curve, - Alignment? alignment, - Animation animation, - Animation secondaryAnimation, - Widget child) { - return SlideTransition( - position: Tween( - begin: const Offset(0.0, -1.0), - end: Offset.zero, - ).animate(animation), - child: child, - ); + BuildContext context, + Curve? curve, + Alignment? alignment, + Animation animation, + Animation secondaryAnimation, + Widget child, + Widget? oldPage, + ) { + return Stack(children: [ + if (oldPage != null) + SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(0.0, 1.0), + ).animate(animation), + child: oldPage, + ), + SlideTransition( + position: Tween( + begin: const Offset(0.0, -1.0), + end: Offset.zero, + ).animate(animation), + child: child, + ), + ]); } } @@ -158,11 +221,15 @@ class ZoomInTransition { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return ScaleTransition( - scale: animation, - child: child, - ); + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) oldPage, + ScaleTransition( + scale: animation, + child: child, + ), + ]); } } @@ -173,17 +240,21 @@ class SizeTransitions { Alignment? alignment, Animation animation, Animation secondaryAnimation, - Widget child) { - return Align( - alignment: Alignment.center, - child: SizeTransition( - sizeFactor: CurvedAnimation( - parent: animation, - curve: curve, + Widget child, + Widget? oldPage) { + return Stack(children: [ + if (oldPage != null) oldPage, + Align( + alignment: Alignment.center, + child: SizeTransition( + sizeFactor: CurvedAnimation( + parent: animation, + curve: curve, + ), + child: child, ), - child: child, ), - ); + ]); } } diff --git a/lib/get_navigation/src/routes/get_route.dart b/lib/get_navigation/src/routes/get_route.dart index 334c50088..be8157f2f 100644 --- a/lib/get_navigation/src/routes/get_route.dart +++ b/lib/get_navigation/src/routes/get_route.dart @@ -12,6 +12,7 @@ import '../../get_navigation.dart'; class GetPage extends Page { final GetPageBuilder page; + final Widget? oldPage; final bool? popGesture; final Map? parameters; final String? title; @@ -56,6 +57,7 @@ class GetPage extends Page { GetPage({ required this.name, required this.page, + this.oldPage, this.title, this.participatesInRootNavigator, this.gestureWidth, @@ -99,6 +101,7 @@ class GetPage extends Page { LocalKey? key, String? name, GetPageBuilder? page, + Widget? oldPage, bool? popGesture, Map? parameters, String? title, @@ -133,6 +136,7 @@ class GetPage extends Page { preventDuplicates: preventDuplicates ?? this.preventDuplicates, name: name ?? this.name, page: page ?? this.page, + oldPage: oldPage ?? this.oldPage, popGesture: popGesture ?? this.popGesture, parameters: parameters ?? this.parameters, title: title ?? this.title, diff --git a/lib/get_navigation/src/routes/get_router_delegate.dart b/lib/get_navigation/src/routes/get_router_delegate.dart index 63a2ea6ec..aaa2dfdac 100644 --- a/lib/get_navigation/src/routes/get_router_delegate.dart +++ b/lib/get_navigation/src/routes/get_router_delegate.dart @@ -358,6 +358,7 @@ class GetDelegate extends RouterDelegate @override Future to( Widget Function() page, { + Widget? oldPage, bool? opaque, Transition? transition, Curve? curve, @@ -385,6 +386,7 @@ class GetDelegate extends RouterDelegate name: routeName, opaque: opaque ?? true, page: page, + oldPage: oldPage, gestureWidth: gestureWidth, showCupertinoParallax: showCupertinoParallax, popGesture: popGesture ?? Get.defaultPopGesture, diff --git a/lib/get_navigation/src/routes/get_transition_mixin.dart b/lib/get_navigation/src/routes/get_transition_mixin.dart index 3af79f9ee..c7d5cc72e 100644 --- a/lib/get_navigation/src/routes/get_transition_mixin.dart +++ b/lib/get_navigation/src/routes/get_transition_mixin.dart @@ -231,6 +231,8 @@ class GetBackGestureController { mixin GetPageRouteTransitionMixin on PageRoute { ValueNotifier? _previousTitle; + Widget? oldPage; + @override Color? get barrierColor => null; @@ -311,7 +313,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { return buildPageTransitions( - this, context, animation, secondaryAnimation, child); + this, context, animation, secondaryAnimation, child, + oldPage: oldPage); } @override @@ -363,6 +366,7 @@ Cannot read the previousTitle for a route that has not yet been installed''', Widget child, { bool limitedSwipe = false, double initialOffset = 0, + Widget? oldPage, }) { // Check if the route has an animation that's currently participating // in a back swipe gesture. @@ -431,7 +435,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.downToUp: return SlideDownTransition().buildTransitions( @@ -452,7 +457,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.upToDown: return SlideTopTransition().buildTransitions( @@ -473,7 +479,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.noTransition: return GetBackGestureDetector( @@ -509,7 +516,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.zoom: return ZoomInTransition().buildTransitions( @@ -530,7 +538,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.fadeIn: return FadeInTransition().buildTransitions( @@ -551,7 +560,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.rightToLeftWithFade: return RightToLeftFadeTransition().buildTransitions( @@ -572,7 +582,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.leftToRightWithFade: return LeftToRightFadeTransition().buildTransitions( @@ -593,7 +604,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.cupertino: return CupertinoPageTransition( @@ -633,27 +645,32 @@ Cannot read the previousTitle for a route that has not yet been installed''', route.gestureWidth?.call(context) ?? _kBackGestureWidth, initialOffset: initialOffset, child: child, - )); + ), + oldPage); case Transition.fade: - return const FadeUpwardsPageTransitionsBuilder().buildTransitions( - route, - context, - animation, - secondaryAnimation, - GetBackGestureDetector( - popGestureEnable: () => - _isPopGestureEnabled(route, canSwipe(route), context), - onStartPopGesture: () { - assert(_isPopGestureEnabled(route, canSwipe(route), context)); - return _startPopGesture(route); - }, - limitedSwipe: limitedSwipe, - gestureWidth: - route.gestureWidth?.call(context) ?? _kBackGestureWidth, - initialOffset: initialOffset, - child: child, - )); + return Stack(children: [ + if (oldPage != null) oldPage, + const FadeUpwardsPageTransitionsBuilder().buildTransitions( + route, + context, + animation, + secondaryAnimation, + GetBackGestureDetector( + popGestureEnable: () => + _isPopGestureEnabled(route, canSwipe(route), context), + onStartPopGesture: () { + assert( + _isPopGestureEnabled(route, canSwipe(route), context)); + return _startPopGesture(route); + }, + limitedSwipe: limitedSwipe, + gestureWidth: + route.gestureWidth?.call(context) ?? _kBackGestureWidth, + initialOffset: initialOffset, + child: child, + )), + ]); case Transition.topLevel: return const ZoomPageTransitionsBuilder().buildTransitions( diff --git a/lib/get_navigation/src/routes/route_middleware.dart b/lib/get_navigation/src/routes/route_middleware.dart index 69a4c31fc..da21a1219 100644 --- a/lib/get_navigation/src/routes/route_middleware.dart +++ b/lib/get_navigation/src/routes/route_middleware.dart @@ -225,7 +225,7 @@ class PageRedirect { popGesture: r.popGesture, fullscreenDialog: r.fullscreenDialog, middlewares: r.middlewares, - ); + )..oldPage = r.oldPage; } /// check if redirect is needed