Browse Source

change Router to FluroRouter to avoid collisions with Router from the new Pages / Navigator 2.0 API

lukepighetti 5 years ago
parent
commit
a96fb1393c

+ 25 - 5
CHANGELOG.md

@@ -1,22 +1,32 @@
+# 1.6.4
+
+- Rename Router to FluroRouter to avoid namespace collisions with the Router class from the new Pages / Navigator 2.0 API.
+
 # 1.6.3
+
 - Remove upper bounds on Flutter SDK checks because Flutter releases are a ridiculous mess
 
 # 1.6.2
+
 - Support for Flutter `>=1.12 <=1.17`
 
 # 1.6.1
+
 - Support for Flutter `1.12+`
 
 # 1.6.0
-- No changes other than fixes for non-backwards compatible Flutter changes 
+
+- No changes other than fixes for non-backwards compatible Flutter changes
 - Flutter `>= 1.12.0` is required due to Flutter compatibility issues
 - Dart `>= 2.6.0` is required
 
 # 1.5.2
+
 - Remove dependency on `dart:io`
-- 1.5.x and lower now only supports Flutter versions `< 1.13.0` 
+- 1.5.x and lower now only supports Flutter versions `< 1.13.0`
 
 # 1.5.1
+
 - Add explicit material and full screen material transition types
 - Fix issue in transition logic
 - Remove redundant `new`, `const`, etc qualifiers
@@ -24,39 +34,49 @@
 - Add font license info
 
 # 1.5.0
+
 - Native transitions will now use the Cupertino page route on iOS and Material page route on android. This will enable swipe gestures on iOS.
-- Added cupertino specific transition types. 
+- Added cupertino specific transition types.
 - **You should not be using Cupertino types on non-iOS platforms. It's up to you, but it's bad design**.
 
 # 1.4.0
+
 - Added the ability to define a transition at the point of route definition. Route transitions are optional and any transition defined a "push" will override the route definition.
 
 # 1.3.7
+
 - Add `toString` for custom `RouteNotFoundException` type
 
 # 1.3.6
+
 - Small fix to error return type when no route match was made
 
 # 1.3.5
+
 - add `pop` convenience
 - add `clearStack` flag so that you can clear the history when pushing a route
 
 # 1.3.4
+
 - Change lower dart version to cater to older flutter versions
 
 # 1.3.3
+
 - Fix analyzer issues
 - Remove deprecations in example code
 - Fix pubspec analysis issue
 
 # 1.3.2
+
 - Dart 2 package (pubspec) compliance changes ONLY
 - **Note**: No functional changes
 
 # 1.3.1
+
 - Fixes an issue with the route generator (result cannot be Null)
 
 # 1.3.0
+
 - **BREAKING**: Parameters now return an array of results even if they have a single value.
 - Support for parameter arrays. e.g: `/some/route?color=red&color=green&color=blue`.
 - Results can now be passed via `Navigator.pop` via use of a `Future`.
@@ -64,8 +84,8 @@
 
 # 1.1.0
 
-**BREAKING**: In order to support function handlers you will need to change all of your route 
-handler definitions to use the new `Handler` class. The `RouteHandler` definition has now been 
+**BREAKING**: In order to support function handlers you will need to change all of your route
+handler definitions to use the new `Handler` class. The `RouteHandler` definition has now been
 removed.
 
 Swapping out the handlers should be as simple as changing:

+ 13 - 9
README.md

@@ -25,19 +25,20 @@ See CHANGELOG for all breaking (and non-breaking) changes.
 ## Getting started
 
 You should ensure that you add the router as a dependency in your flutter project.
+
 ```yaml
 dependencies:
- fluro: "^1.6.3"
+  fluro: "^1.6.4"
 ```
 
 You can also reference the git repo directly if you want:
+
 ```yaml
 dependencies:
- fluro:
-   git: git://github.com/theyakka/fluro.git
+  fluro:
+    git: git://github.com/theyakka/fluro.git
 ```
 
-
 You should then run `flutter packages upgrade` or update your packages in IntelliJ.
 
 ## Example Project
@@ -46,20 +47,23 @@ There is a pretty sweet example project in the `example` folder. Check it out. O
 
 ## Setting up
 
-First, you should define a new `Router` object by initializing it as such:
+First, you should define a new `FluroRouter` object by initializing it as such:
+
 ```dart
-final router = Router();
+final router = FluroRouter();
 ```
+
 It may be convenient for you to store the router globally/statically so that
 you can access the router in other areas in your application.
 
 After instantiating the router, you will need to define your routes and your route handlers:
+
 ```dart
 var usersHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) {
   return UsersScreen(params["id"][0]);
 });
 
-void defineRoutes(Router router) {
+void defineRoutes(FluroRouter router) {
   router.define("/users/:id", handler: usersHandler);
 
   // it is also possible to define the route transition to use
@@ -73,8 +77,8 @@ the value `1234` as a parameter to that screen.
 
 ## Navigating
 
-You can use the `Router` with the `MaterialApp.onGenerateRoute` parameter
-via the `Router.generator` function. To do so, pass the function reference to
+You can use `FluroRouter` with the `MaterialApp.onGenerateRoute` parameter
+via `FluroRouter.generator`. To do so, pass the function reference to
 the `onGenerate` parameter like: `onGenerateRoute: router.generator`.
 
 You can then use `Navigator.push` and the flutter routing mechanism will match the routes

+ 1 - 0
example/ios/Flutter/.last_build_id

@@ -0,0 +1 @@
+ec6724256ae435d1dca5b22a58b37a5d

+ 9 - 4
example/ios/Flutter/flutter_export_environment.sh

@@ -1,11 +1,16 @@
 #!/bin/sh
 # This is a generated file; do not edit or check into version control.
-export "FLUTTER_ROOT=/home/luke/Development/.sdks/flutter"
-export "FLUTTER_APPLICATION_PATH=/home/luke/Development/yakka/fluro/fluro-flutter/example"
-export "FLUTTER_TARGET=lib/main.dart"
+export "FLUTTER_ROOT=/Users/lukepighetti/development/flutter"
+export "FLUTTER_APPLICATION_PATH=/Users/lukepighetti/development/misc/fluro/example"
+export "FLUTTER_TARGET=/Users/lukepighetti/development/misc/fluro/example/lib/main.dart"
 export "FLUTTER_BUILD_DIR=build"
 export "SYMROOT=${SOURCE_ROOT}/../build/ios"
 export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
-export "FLUTTER_FRAMEWORK_DIR=/home/luke/Development/.sdks/flutter/bin/cache/artifacts/engine/ios"
+export "FLUTTER_FRAMEWORK_DIR=/Users/lukepighetti/development/flutter/bin/cache/artifacts/engine/ios"
 export "FLUTTER_BUILD_NAME=1.0.0"
 export "FLUTTER_BUILD_NUMBER=1"
+export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue"
+export "DART_OBFUSCATION=false"
+export "TRACK_WIDGET_CREATION=true"
+export "TREE_SHAKE_ICONS=false"
+export "PACKAGE_CONFIG=.packages"

+ 1 - 15
example/ios/Runner.xcodeproj/project.pbxproj

@@ -8,11 +8,7 @@
 
 /* Begin PBXBuildFile section */
 		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
-		3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
-		3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		41FA87031F2620DA005CDA4D /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 41FA87021F2620DA005CDA4D /* GeneratedPluginRegistrant.m */; };
-		9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
-		9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
 		9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; };
 		978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
@@ -29,8 +25,6 @@
 			dstPath = "";
 			dstSubfolderSpec = 10;
 			files = (
-				3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
-				9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
 			);
 			name = "Embed Frameworks";
 			runOnlyForDeploymentPostprocessing = 0;
@@ -39,7 +33,6 @@
 
 /* Begin PBXFileReference section */
 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
-		3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
 		41FA87011F2620DA005CDA4D /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
 		41FA87021F2620DA005CDA4D /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@@ -47,7 +40,6 @@
 		7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
 		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
 		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
-		9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
 		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@@ -61,8 +53,6 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
-				3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -72,9 +62,7 @@
 		9740EEB11CF90186004384FC /* Flutter */ = {
 			isa = PBXGroup;
 			children = (
-				3B80C3931E831B6300D905FE /* App.framework */,
 				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
-				9740EEBA1CF902C7004384FC /* Flutter.framework */,
 				9740EEB21CF90195004384FC /* Debug.xcconfig */,
 				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
 				9740EEB31CF90195004384FC /* Generated.xcconfig */,
@@ -208,7 +196,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
 		};
 		9740EEB61CF901F6004384FC /* Run Script */ = {
 			isa = PBXShellScriptBuildPhase;
@@ -261,7 +249,6 @@
 /* Begin XCBuildConfiguration section */
 		97C147031CF9000F007C117D /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
@@ -309,7 +296,6 @@
 		};
 		97C147041CF9000F007C117D /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;

+ 1 - 1
example/lib/components/app/app_component.dart

@@ -21,7 +21,7 @@ class AppComponent extends StatefulWidget {
 
 class AppComponentState extends State<AppComponent> {
   AppComponentState() {
-    final router = Router();
+    final router = FluroRouter();
     Routes.configureRoutes(router);
     Application.router = router;
   }

+ 1 - 1
example/lib/config/application.dart

@@ -9,5 +9,5 @@
 import 'package:fluro/fluro.dart';
 
 class Application {
-  static Router router;
+  static FluroRouter router;
 }

+ 1 - 1
example/lib/config/routes.dart

@@ -17,7 +17,7 @@ class Routes {
   static String demoFunc = "/demo/func";
   static String deepLink = "/message";
 
-  static void configureRoutes(Router router) {
+  static void configureRoutes(FluroRouter router) {
     router.notFoundHandler = Handler(
         handlerFunc: (BuildContext context, Map<String, List<String>> params) {
       print("ROUTE WAS NOT FOUND !!!");

+ 1 - 0
lib/fluro.dart

@@ -10,4 +10,5 @@ library fluro;
 
 export 'src/common.dart';
 export 'src/router.dart';
+export 'src/fluro_router.dart';
 export 'src/tree.dart';

+ 231 - 0
lib/src/fluro_router.dart

@@ -0,0 +1,231 @@
+/*
+ * fluro
+ * Created by Yakka
+ * https://theyakka.com
+ * 
+ * Copyright (c) 2019 Yakka, LLC. All rights reserved.
+ * See LICENSE for distribution and usage details.
+ */
+
+import 'dart:async';
+
+import 'package:fluro/fluro.dart';
+import 'package:fluro/src/common.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class FluroRouter {
+  static final appRouter = FluroRouter();
+
+  /// The tree structure that stores the defined routes
+  final RouteTree _routeTree = RouteTree();
+
+  /// Generic handler for when a route has not been defined
+  Handler notFoundHandler;
+
+  /// Creates a [PageRoute] definition for the passed [RouteHandler]. You can optionally provide a default transition type.
+  void define(String routePath,
+      {@required Handler handler, TransitionType transitionType}) {
+    _routeTree.addRoute(
+      AppRoute(routePath, handler, transitionType: transitionType),
+    );
+  }
+
+  /// Finds a defined [AppRoute] for the path value. If no [AppRoute] definition was found
+  /// then function will return null.
+  AppRouteMatch match(String path) {
+    return _routeTree.matchRoute(path);
+  }
+
+  void pop(BuildContext context) => Navigator.pop(context);
+
+  ///
+  Future navigateTo(BuildContext context, String path,
+      {bool replace = false,
+      bool clearStack = false,
+      TransitionType transition,
+      Duration transitionDuration = const Duration(milliseconds: 250),
+      RouteTransitionsBuilder transitionBuilder}) {
+    RouteMatch routeMatch = matchRoute(context, path,
+        transitionType: transition,
+        transitionsBuilder: transitionBuilder,
+        transitionDuration: transitionDuration);
+    Route<dynamic> route = routeMatch.route;
+    Completer completer = Completer();
+    Future future = completer.future;
+    if (routeMatch.matchType == RouteMatchType.nonVisual) {
+      completer.complete("Non visual route type.");
+    } else {
+      if (route == null && notFoundHandler != null) {
+        route = _notFoundRoute(context, path);
+      }
+      if (route != null) {
+        if (clearStack) {
+          future =
+              Navigator.pushAndRemoveUntil(context, route, (check) => false);
+        } else {
+          future = replace
+              ? Navigator.pushReplacement(context, route)
+              : Navigator.push(context, route);
+        }
+        completer.complete();
+      } else {
+        String error = "No registered route was found to handle '$path'.";
+        print(error);
+        completer.completeError(RouteNotFoundException(error, path));
+      }
+    }
+
+    return future;
+  }
+
+  ///
+  Route<Null> _notFoundRoute(BuildContext context, String path) {
+    RouteCreator<Null> creator =
+        (RouteSettings routeSettings, Map<String, List<String>> parameters) {
+      return MaterialPageRoute<Null>(
+          settings: routeSettings,
+          builder: (BuildContext context) {
+            return notFoundHandler.handlerFunc(context, parameters);
+          });
+    };
+    return creator(RouteSettings(name: path), null);
+  }
+
+  ///
+  RouteMatch matchRoute(BuildContext buildContext, String path,
+      {RouteSettings routeSettings,
+      TransitionType transitionType,
+      Duration transitionDuration = const Duration(milliseconds: 250),
+      RouteTransitionsBuilder transitionsBuilder}) {
+    RouteSettings settingsToUse = routeSettings;
+    if (routeSettings == null) {
+      settingsToUse = RouteSettings(name: path);
+    }
+    AppRouteMatch match = _routeTree.matchRoute(path);
+    AppRoute route = match?.route;
+    Handler handler = (route != null ? route.handler : notFoundHandler);
+    var transition = transitionType;
+    if (transitionType == null) {
+      transition = route != null ? route.transitionType : TransitionType.native;
+    }
+    if (route == null && notFoundHandler == null) {
+      return RouteMatch(
+          matchType: RouteMatchType.noMatch,
+          errorMessage: "No matching route was found");
+    }
+    Map<String, List<String>> parameters =
+        match?.parameters ?? <String, List<String>>{};
+    if (handler.type == HandlerType.function) {
+      handler.handlerFunc(buildContext, parameters);
+      return RouteMatch(matchType: RouteMatchType.nonVisual);
+    }
+
+    RouteCreator creator =
+        (RouteSettings routeSettings, Map<String, List<String>> parameters) {
+      bool isNativeTransition = (transition == TransitionType.native ||
+          transition == TransitionType.nativeModal);
+      if (isNativeTransition) {
+        if (Theme.of(buildContext).platform == TargetPlatform.iOS) {
+          return CupertinoPageRoute<dynamic>(
+              settings: routeSettings,
+              fullscreenDialog: transition == TransitionType.nativeModal,
+              builder: (BuildContext context) {
+                return handler.handlerFunc(context, parameters);
+              });
+        } else {
+          return MaterialPageRoute<dynamic>(
+              settings: routeSettings,
+              fullscreenDialog: transition == TransitionType.nativeModal,
+              builder: (BuildContext context) {
+                return handler.handlerFunc(context, parameters);
+              });
+        }
+      } else if (transition == TransitionType.material ||
+          transition == TransitionType.materialFullScreenDialog) {
+        return MaterialPageRoute<dynamic>(
+            settings: routeSettings,
+            fullscreenDialog:
+                transition == TransitionType.materialFullScreenDialog,
+            builder: (BuildContext context) {
+              return handler.handlerFunc(context, parameters);
+            });
+      } else if (transition == TransitionType.cupertino ||
+          transition == TransitionType.cupertinoFullScreenDialog) {
+        return CupertinoPageRoute<dynamic>(
+            settings: routeSettings,
+            fullscreenDialog:
+                transition == TransitionType.cupertinoFullScreenDialog,
+            builder: (BuildContext context) {
+              return handler.handlerFunc(context, parameters);
+            });
+      } else {
+        var routeTransitionsBuilder;
+        if (transition == TransitionType.custom) {
+          routeTransitionsBuilder = transitionsBuilder;
+        } else {
+          routeTransitionsBuilder = _standardTransitionsBuilder(transition);
+        }
+        return PageRouteBuilder<dynamic>(
+          settings: routeSettings,
+          pageBuilder: (BuildContext context, Animation<double> animation,
+              Animation<double> secondaryAnimation) {
+            return handler.handlerFunc(context, parameters);
+          },
+          transitionDuration: transitionDuration,
+          transitionsBuilder: routeTransitionsBuilder,
+        );
+      }
+    };
+    return RouteMatch(
+      matchType: RouteMatchType.visual,
+      route: creator(settingsToUse, parameters),
+    );
+  }
+
+  RouteTransitionsBuilder _standardTransitionsBuilder(
+      TransitionType transitionType) {
+    return (BuildContext context, Animation<double> animation,
+        Animation<double> secondaryAnimation, Widget child) {
+      if (transitionType == TransitionType.fadeIn) {
+        return FadeTransition(opacity: animation, child: child);
+      } else {
+        const Offset topLeft = const Offset(0.0, 0.0);
+        const Offset topRight = const Offset(1.0, 0.0);
+        const Offset bottomLeft = const Offset(0.0, 1.0);
+        Offset startOffset = bottomLeft;
+        Offset endOffset = topLeft;
+        if (transitionType == TransitionType.inFromLeft) {
+          startOffset = const Offset(-1.0, 0.0);
+          endOffset = topLeft;
+        } else if (transitionType == TransitionType.inFromRight) {
+          startOffset = topRight;
+          endOffset = topLeft;
+        }
+
+        return SlideTransition(
+          position: Tween<Offset>(
+            begin: startOffset,
+            end: endOffset,
+          ).animate(animation),
+          child: child,
+        );
+      }
+    };
+  }
+
+  /// Route generation method. This function can be used as a way to create routes on-the-fly
+  /// if any defined handler is found. It can also be used with the [MaterialApp.onGenerateRoute]
+  /// property as callback to create routes that can be used with the [Navigator] class.
+  Route<dynamic> generator(RouteSettings routeSettings) {
+    RouteMatch match =
+        matchRoute(null, routeSettings.name, routeSettings: routeSettings);
+    return match.route;
+  }
+
+  /// Prints the route tree so you can analyze it.
+  void printTree() {
+    _routeTree.printTree();
+  }
+}

+ 9 - 4
lib/src/router.dart

@@ -11,10 +11,15 @@ import 'dart:async';
 
 import 'package:fluro/fluro.dart';
 import 'package:fluro/src/common.dart';
-import 'package:flutter/foundation.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-
+import 'package:flutter/cupertino.dart' hide Router;
+import 'package:flutter/material.dart' hide Router;
+import 'package:flutter/material.dart' as material;
+
+/// Router has been renamed to [FluroRouter] to avoid namespace collisions with
+/// Flutter's new [material.Router] class from the Pages / Navigator 2.0 API.
+///
+/// [FluroRouter] is identical to [Router].
+@Deprecated('Use FluroRouter instead')
 class Router {
   static final appRouter = Router();
 

+ 1 - 1
pubspec.yaml

@@ -2,7 +2,7 @@ name: fluro
 description: >
   Fluro is a Flutter routing library that adds flexible routing options like wildcards, named
   parameters and clear route definitions.
-version: 1.6.3
+version: 1.6.4
 homepage: https://github.com/theyakka/fluro
 
 environment: