If your app does not rely on the return value of Navigator.pop, manage the life cycles of the overlay entries of routes, override Route.install, or rely on the isInitialRoute in RouteSetting, you can stop reading now.
While we are refactoring Navigator according to this design document, we would like to make several changes to our current apis.
Firstly, we would like to change the function signature of Navigator.pop to return void instead of a boolean value.
Secondly, we would like to change the function signature of Route.install to not take positional argument insertionPoint, as well as the overlayEntries must have at least one overlay entry after Route.install is called.
Thirdly, the Route.dispose will not remove its overlayEntries from the overlay. The Navigator that owns the route will be in charge of adding and removing its overlay entries from overlay.
Finally, we also would like to deprecate isInitialRoute and eventually remove it once the page api is added to the framework.
For more information, please refer to the design document.
Change PR
The boolean return value of the Navigator.pop is not well defined and user can achieve the same result by calling the Navigator.canPop. Since the api of Navigator.canPop is better defined, we would like to simplify the Navigator.pop to not return the boolean value.
While we are refactoring navigator for the upcoming page api, the navigator would require the ability to manually rearrange overlay entries in the overlay to allow user to change routes history use the new api. Our current structure does not allow it because the route manages its own overlay entries in the overlay, and the navigator does not access them directly. We would like to change it so that the route only creates and destroys its overlay entries while the navigator inserts or removes overlay entries from the overlay. This change also makes the insertionPoint argument of Route.install obsolete, and we would like to remove it as part of this breaking change.
The page api also provides the ability to reorder initial routes. This will make isInitialRoute inconsistent during the app's lifetime. An initial route might become non-initial route and vise-versa, and a route will need to be rebuilt if its RouteSetting has been updated. Changing the route history will cause all the routes to be rebuilt, and that defeat the purpose of the page api. We would like to remove the isInitialRoute property from the RouteSetting, so that the current route structure will still work with the new api.
https://github.com/flutter/flutter/issues/45938
Case 1: An app has dependency of pop to return a boolean value
TextField(
onTap: () {
if (Navigator.pop(context))
print(‘There still is at least one route after pop’);
Else
print(‘Oops! No more route.’);
}
)
After migration:
TextField(
onTap: () {
if (Navigator.canPop(context))
print(‘There still is at least one route after pop’);
Else
print(‘Oops! No more route.’);
// Our navigator will pop the route anyway.
Navigator.pop(context);
}
)
Case2: An app generate routes based on isInitialRoute
MaterialApp(
onGenerateRoute: (RouteSetting setting) {
if (setting.isInitialRoute)
return FakeSplashRoute();
else
return RealRoute(setting);
}
)
There are different ways to migrate this app. One way is to make sure to set initial route name to a fixed value and generate a specific route (FakeSplashRoute in the above example) for the route name.
MaterialApp(
initialRouteName: ‘fakeSplash’,
onGenerateRoute: (RouteSetting setting) {
if (setting.name == ‘fakeSplash’)
return FakeSplashRoute();
else
return RealRoute(setting);
}
)
If there is a more complicated use case, we provide a new api, onGenerateInitialRoutes, in MaterialApp/CupertinoApp.
MaterialApp(
onGenerateRoute: (RouteSetting setting) {
return RealRoute(setting);
},
onGenerateInitialRoutes: (String initialRouteName) {
return <Route>[FakeSplashRoute()];
}
)
If you have any issues migrating or questions about this change, feel free to comment on the issue.
Cheers,
Chun-Heng