navigation_util.dart 3.4 KB

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