The jump function
This section provides an example for jumping to common pages.
Ordinary jump
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => NextPage1(),
),
);
Copy the code
Named after the jump
Navigator.of(context).pushNamed("/router/nextPage");
Copy the code
The premise is that the routing table needs to be configured in the main entry of the program
MaterialApp(
navigatorObservers: [UserNavigatorObserver()],
initialRoute: "/",
routes: {
"/router": (context) => RouterDemo(),
"/router/nextPage": (context) => NextPage2(),
},
);
Copy the code
Exit pages
Navigator.of(context).pop(); Navigation.of (context).maybepop (); // Do not exit for the last page in the stackCopy the code
Advanced usage
popAndPushNamed
Exit the current page and go to a new page
Navigator.of(context).popAndPushNamed("/router/nextPage");
Copy the code
Equivalent to the following
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => NextPage1(),
),
);
Copy the code
PS: If the current page is the root page of the stack, will pop be executed before push and popAndPushNamed? If you look at the source code, you can see that popAndPushNamed is just pop first and then push, so the result is the same.
@optionalTypeArgs
Future<T> popAndPushNamed<T extends Object, TO extends Object>(
String routeName, {
TO result,
Object arguments,
}) {
pop<TO>(result);
return pushNamed<T>(routeName, arguments: arguments);
}
Copy the code
pushReplacementNamed
Similar to popAndPushNamed, you exit the current page and jump to a new page. While popAndPushNamed has both the out and push animations, pushReplacementNamed has only the push animations
Navigator.of(context).pushReplacementNamed("/router/next5");
Copy the code
pushNamedAndRemoveUntil
The code “modalRoute.withName (“/”)” is to back the routing stack to the root route and jump to the “/ router/nextPage “named route. For example, if the current routing stack is [1,2,3,4], run the pushNamedAndRemoveUntil command to open new page 5, set modalroute. withName to 2, and set the routing stack to [1,2,5]. Common scenarios For example, in the personal Settings page, skip to multiple submenus and then directly return to the home page.
Navigator.of(context).pushNamedAndRemoveUntil(
"/router/nextPage",
ModalRoute.withName("/"),
);
Copy the code
Modalroute.withname (“/”) (“/”); / /” /” (“/”); / /” /” (“/”); I wonder if this is a problem with the design of the Flutter route. I haven’t found a modalroute.withname alternative yet, so the back page route must be a named route.
removeRoute
Route stack removal. For example, modalRoute. of(context) can be used to obtain the current page route. If you compare it to navigater.of (context).pop(), you can remove the route from the stack as soon as you get the corresponding route object. Navigater.of (context).pop() can only remove the current routing page.
Navigator.of(context).removeRoute(ModalRoute.of(context));
Copy the code
removeRouteBelow
The same is the routing stack removal function, according to the input page route to remove the anchor point route of the last page route. For example, if the routing stack is [1,2,3,4], run removeRouteBelow(3) to change the routing stack to [1,3,4].
Navigator.of(context).removeRouteBelow(ModalRoute.of(context));
Copy the code
replace
Replace routing stack functionality, similar to pushReplacementNamed.
PS:The old route must not be currently visible
The replace method is described in the official documentation and cannot be used for top stack routing. Therefore, this method can not be used for the current route, can remove the previous or stack route.
So you can finally get the specified route and remove it from the stack using the global routing stack array history in the UserNavigatorObserver.
Navigator.of(context).replace(
oldRoute: UserNavigatorObserver
.history[UserNavigatorObserver.history.length - 2],
newRoute: MaterialPageRoute(
builder: (_) => NextPage1(),
),
);
Copy the code
For example, if the routing stack is [1,2,3,4],replace(3,5) changes the routing stack to [1,2,5,4].
replaceRouteBelow
Replace routing stack functionality with removeRouteBelow. Replace input route Replaces the previous page route of the anchor point route. Finally, as with replace, it does not apply to the current page route.
Navigator.of(context).replaceRouteBelow(
anchorRoute: UserNavigatorObserver
.history[UserNavigatorObserver.history.length - 2],
newRoute: MaterialPageRoute(
builder: (_) => NextPage1(),
),
);
Copy the code
For example, if the routing stack is [1,2,3,4],replace(3,5) changes the routing stack to [1,5,3,4].
The parameter function
Routing also supports parameter passing between pages
Into the parameter passed
The route jump passes the desired incoming arguments through the Arguments field. We can set arguments to pass more incoming arguments to the Map object. Named routes pass arguments directly through the Arguments field. Direct routes pass Arguments directly through the Settings field created in the RouteSettings object.
- To name the route to jump
Navigator.of(context).pushNamed(
"/router/data2",
arguments: {"data": "Hello"},
);
Copy the code
- To jump to the page
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChildDataDemo4(),
settings: RouteSettings(
arguments: {"data": "Hello"},
),
),
);
Copy the code
The receiving page obtains data from the input parameter arguments using modalRoute.of (context).settings.
class RouterChildDateDemo2 extends StatefulWidget { @override _RouterChildDateDemo2State createState() => _RouterChildDateDemo2State(); } class _RouterChildDateDemo2State extends State<RouterChildDateDemo2> { @override Widget build(BuildContext context) { Map arguments = ModalRoute.of(context).settings.arguments; String data = arguments['data']; return Scaffold( appBar: AppBar(), body: Column( children: <Widget>[ Text("data: $data"), ], ), ); }}Copy the code
- Construct with direct route
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChildDateDemo3("Hello"),
),
);
Copy the code
The data receiving page gets the incoming parameters through the widget. Of course, this way of coupling is too high, not recommended for late maintenance (although MY own projects are written so, refactoring workload is huge 😿).
class ChildDateDemo3 extends StatefulWidget { final String data; ChildDateDemo3(this.data); @override _ChildDateDemo3State createState() => _ChildDateDemo3State(); } class _ChildDateDemo3State extends State<ChildDateDemo3> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Column( children: <Widget>[ Text("data: ${widget.data}"), ], ), ); }}Copy the code
If pass due to the context context and need to use in initState, use SchedulerBinding. Instance. AddPostFrameCallback acquisition parameters.
SchedulerBinding.instance.addPostFrameCallback((_) {
Map arguments = ModalRoute.of(context).settings.arguments;
cusip = arguments["cusip"];
});
Copy the code
Parameters of return
In addition to the input parameters, we certainly want to be able to get the return value as well as pass the parameters. For example, when you go to a Settings page, you get the Settings data from the previous page and display it on return (although global state management is a good substitute for this).
The route jump method has the return value Future, set the jump method to async and get the result with await.
var result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChildDataDemo5(),
),
);
setState(() {
this.result = result.toString();
});
Copy the code
Passing in the POP method requires returning generic parameters (using a dictionary is a good data structure) when returning the result of the parent page return.
Navigator.of(context).pop({"data": "Bye"});
Copy the code
The animation transition
Replace the MaterialPageRoute with the PageRouteBuilder to do the route jump. Animation effects are realized by creating an AnimatedWidget object with transitionsBuilder. Set a SlideTransition animation below to create a side slide out effect by starting and ending offsets
Navigator.of(context).push( PageRouteBuilder( pageBuilder: (BuildContext context, Animation<double> animation1, Animation<double> animation2) { return AniDemo2(); }, transitionsBuilder: (BuildContext context, Animation<double> animation1, Animation<double> animation2, Widget child) {return SlideTransition(position: Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0),). Animate (animation1,), child: child,); },),);Copy the code
Global route monitoring
The route also supports the listening function. NavigatorObserver allows you to obtain real-time routing information. Create a NavigatorObserver in the root component. Create a UserNavigatorObserver and inherit the NavigatorObserver to record the global stack information through the callback interface. Here’s how the NavigatorObserver callback interface triggers.
MaterialApp(
navigatorObservers: [UserNavigatorObserver()],
......
)
Copy the code
Inherits NavigatorObserver and adds the global History stack information management array.
class UserNavigatorObserver extends NavigatorObserver { static List<Route<dynamic>> history = <Route<dynamic>>[]; @override void didPop(Route route, Route previousRoute) { super.didPop(route, previousRoute); history.remove(route); /// Call navigator.of (context).pop();} @override void didPush(Route Route, Route Route, Route previousRoute) { super.didPush(route, previousRoute); history.add(route); /// call navigator.of (context).push(Route()) callback @override void didRemove(Route Route, Route previousRoute) { super.didRemove(route, previousRoute); history.remove(route); /// Call navigation.of (context).removeroute (Route()) to remove a Route callback} @override void didReplace({Route newRoute, Route oldRoute}) { super.didReplace(newRoute: newRoute, oldRoute: oldRoute); history.remove(oldRoute); history.add(newRoute); Of (context).replace(oldRoute:Route("old"),newRoute:Route("new"))} @override void didStartUserGesture(Route route, Route previousRoute) { super.didStartUserGesture(route, previousRoute); } @override void didStopUserGesture() {super.didStopUserGesture(); ///iOS side gesture swipe triggers stop callback is called regardless of whether the page exits or not}}Copy the code
didPop
Call back when navigator.of (context).pop() or another offstack method is called
didPush
Call back to navigator.of (context).push(Route()) or other push methods
didRemove
Call navigator.of (context).removeroute (Route()) to remove a Route callback
didReplace
Call back to Navigator. Of (context).replace(oldRoute:Route(“old”),newRoute:Route(“new”))
didStartUserGesture
IOS Side gesture swipe triggers callback callback when a gesture starts
didStopUserGesture
The iOS side gesture swipe triggers a stop callback that is called regardless of whether the page exits
🚀 See here 🚀 for the full code
reference
- Medium.com/flutter-com…