Line data Source code
1 : import 'package:flutter/material.dart'; 2 : 3 : import '../destination.dart'; 4 : import '../navigation_controller.dart'; 5 : 6 : /// Builds a widget that wraps a content for [NavigationController]. 7 : /// 8 : /// See also: 9 : /// - [DefaultNavigatorBuilder] 10 : /// - [BottomNavigationBuilder] 11 : /// 12 : abstract class NavigatorBuilder { 13 : /// Returns a widget that wraps a content of navigator's destinations. 14 : /// 15 : Widget build(BuildContext context, NavigationController navigator); 16 : } 17 : 18 : /// Implementation of [NavigatorBuilder] that wraps destination's content into 19 : /// [Navigator] widget. 20 : /// 21 : class DefaultNavigatorBuilder implements NavigatorBuilder { 22 : /// Creates default navigator builder. 23 : /// 24 10 : const DefaultNavigatorBuilder(); 25 : 26 3 : @override 27 : Widget build(BuildContext context, NavigationController navigator) { 28 3 : final pages = <_TheseusPage>[]; 29 12 : for (int i = 0; i < navigator.stack.length; i++) { 30 6 : final destination = navigator.stack[i]; 31 6 : pages.add(_TheseusPage( 32 : // TODO: Remove reference to 'i' in the key 33 9 : key: ValueKey('${destination.uri}-$i'), 34 : destination: destination, 35 : )); 36 : } 37 3 : return Navigator( 38 3 : key: navigator.key, 39 : pages: pages, 40 0 : onPopPage: (route, result) { 41 0 : navigator.goBack(); 42 0 : route.didPop(result); 43 : return true; 44 : }, 45 : ); 46 : } 47 : } 48 : 49 : class _TheseusPage extends Page { 50 3 : const _TheseusPage({ 51 : required this.destination, 52 : required LocalKey key, 53 3 : }) : super(key: key); 54 : 55 : final Destination destination; 56 : 57 3 : @override 58 : Route createRoute(BuildContext context) { 59 9 : switch (destination.settings.transition) { 60 3 : case DestinationTransition.material: 61 3 : return MaterialPageRoute( 62 : settings: this, 63 9 : builder: (context) => destination.build(context), 64 : ); 65 0 : case DestinationTransition.materialDialog: 66 0 : return DialogRoute( 67 : context: context, 68 : settings: this, 69 0 : builder: (context) => destination.build(context), 70 : ); 71 0 : case DestinationTransition.custom: 72 0 : return PageRouteBuilder( 73 : settings: this, 74 0 : pageBuilder: (context, animation, secondaryAnimation) => 75 0 : destination.build(context), 76 0 : transitionsBuilder: destination.settings.transitionBuilder!, 77 : ); 78 : case DestinationTransition.none: 79 : default: 80 0 : return PageRouteBuilder( 81 : settings: this, 82 0 : pageBuilder: (context, animation, secondaryAnimation) => 83 0 : destination.build(context), 84 0 : transitionsBuilder: (context, animation, secondaryAnimation, child) => 85 : child, 86 : ); 87 : } 88 : } 89 : }