navigation_util.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. Future<T?> routeToPage<T extends Object>(
  4. BuildContext context,
  5. Widget page, {
  6. bool forceCustomPageRoute = false,
  7. }) {
  8. if (Platform.isAndroid || forceCustomPageRoute) {
  9. return Navigator.of(context).push(
  10. _buildPageRoute(page),
  11. );
  12. } else {
  13. return Navigator.of(context).push(
  14. SwipeableRouteBuilder(
  15. pageBuilder: (context, animation, secondaryAnimation) {
  16. return page;
  17. },
  18. ),
  19. );
  20. }
  21. }
  22. void replacePage(
  23. BuildContext context,
  24. Widget page, {
  25. Object? result,
  26. }) {
  27. Navigator.of(context).pushReplacement(
  28. _buildPageRoute(page),
  29. result: result,
  30. );
  31. }
  32. PageRouteBuilder<T> _buildPageRoute<T extends Object>(Widget page) {
  33. return PageRouteBuilder(
  34. pageBuilder: (
  35. BuildContext context,
  36. Animation<double> animation,
  37. Animation<double> secondaryAnimation,
  38. ) {
  39. return page;
  40. },
  41. transitionsBuilder: (
  42. BuildContext context,
  43. Animation<double> animation,
  44. Animation<double> secondaryAnimation,
  45. Widget child,
  46. ) {
  47. return Align(
  48. child: FadeTransition(
  49. opacity: animation,
  50. child: child,
  51. ),
  52. );
  53. },
  54. transitionDuration: const Duration(milliseconds: 200),
  55. opaque: false,
  56. );
  57. }
  58. class SwipeableRouteBuilder<T> extends PageRoute<T> {
  59. final RoutePageBuilder pageBuilder;
  60. final PageTransitionsBuilder matchingBuilder =
  61. const CupertinoPageTransitionsBuilder(); // Default iOS/macOS (to get the swipe right to go back gesture)
  62. // final PageTransitionsBuilder matchingBuilder = const FadeUpwardsPageTransitionsBuilder(); // Default Android/Linux/Windows
  63. SwipeableRouteBuilder({required this.pageBuilder});
  64. @override
  65. Null get barrierColor => null;
  66. @override
  67. Null get barrierLabel => null;
  68. @override
  69. Widget buildPage(
  70. BuildContext context,
  71. Animation<double> animation,
  72. Animation<double> secondaryAnimation,
  73. ) {
  74. return pageBuilder(context, animation, secondaryAnimation);
  75. }
  76. @override
  77. bool get maintainState => true;
  78. @override
  79. Duration get transitionDuration => const Duration(
  80. milliseconds: 300,
  81. ); // Can give custom Duration, unlike in MaterialPageRoute
  82. @override
  83. Widget buildTransitions(
  84. BuildContext context,
  85. Animation<double> animation,
  86. Animation<double> secondaryAnimation,
  87. Widget child,
  88. ) {
  89. return matchingBuilder.buildTransitions<T>(
  90. this,
  91. context,
  92. animation,
  93. secondaryAnimation,
  94. child,
  95. );
  96. }
  97. @override
  98. bool get opaque => false;
  99. }
  100. class TransparentRoute extends PageRoute<void> {
  101. TransparentRoute({
  102. required this.builder,
  103. RouteSettings? settings,
  104. }) : assert(builder != null),
  105. super(settings: settings, fullscreenDialog: false);
  106. final WidgetBuilder? builder;
  107. @override
  108. bool get opaque => false;
  109. @override
  110. Null get barrierColor => null;
  111. @override
  112. Null get barrierLabel => null;
  113. @override
  114. bool get maintainState => true;
  115. @override
  116. Duration get transitionDuration => const Duration(milliseconds: 200);
  117. @override
  118. Widget buildPage(
  119. BuildContext context,
  120. Animation<double> animation,
  121. Animation<double> secondaryAnimation,
  122. ) {
  123. final result = builder!(context);
  124. return FadeTransition(
  125. opacity: Tween<double>(begin: 0, end: 1).animate(animation),
  126. child: Semantics(
  127. scopesRoute: true,
  128. explicitChildNodes: true,
  129. child: result,
  130. ),
  131. );
  132. }
  133. }