Route chapter of actual combat record of flutter online project

Time:2020-9-30

1. Application scenarios

Often encountered in development

  • What to do if you can’t get the context when the route jumps. Eg: token is invalid / log in to jump to the login page.
  • What to do if the current route name cannot be obtained. Eg: click push to jump to the specified route. If it is already on the current page, replace it; if not, push it.
  • Register to listen to route jump, do something you want to do, eg: different routes, display different status bar colors.
  • wait…

2. Solutions

Solution:

  1. The routes property of materialapplicat assigns the routing array, and the navigatorobservers property assigns the route listening object, navigator manager.
  2. Implement didpush / didreplace / didpop / didremove of navigator observer in navigator manager, and record it to routing stack list_ Mroutes.
  3. Jump the route recorded in real time, send a broadcast with stream, and register where necessary.

3. Specific implementation

main.dart


MaterialApp(
 navigatorObservers: [NavigatorManager.getInstance()],
 routes: NavigatorManager.configRoutes,
 ...
)

navigator_manager.dart

class NavigatorManager extends NavigatorObserver {
 /*Configure routes*/
 static Map<String, WidgetBuilder> configRoutes = {
 PackageInfoPage.sName: (context) =>
 SplashPage.sName: (context) => SplashPage(),
 LoginPage.sName: (context) => SplashPage()),
 MainPage.sName: (context) => SplashPage(),
 //...
 }
 //Current routing stack
 static List<Route> _mRoutes;
 List<Route> get routes => _mRoutes;
 //Current route
 Route get currentRoute => _mRoutes[_mRoutes.length - 1];
 //Stream correlation
 static StreamController _streamController;
 StreamController get streamController=> _streamController;
 //Used to route jumps
 static NavigatorState navigator;
 
 /*A single example is given to show the navigator manager*/
 static NavigatorManager navigatorManager;
 static NavigatorManager getInstance() {
 if (navigatorManager == null) {
  navigatorManager = new NavigatorManager();
  _streamController = StreamController.broadcast();
 }
 return navigatorManager;
 }
 
 //Replace page
 pushReplacementNamed(String routeName, [WidgetBuilder builder]) {
 return navigator.pushReplacement(
  CupertinoPageRoute(
  builder: builder ?? configRoutes[routeName],
  settings: RouteSettings(name: routeName),
  ),
 );
 }
 
 //Push page
 pushNamed(String routeName, [WidgetBuilder builder]) {
 return navigator.push(
  CupertinoPageRoute(
  builder: builder ?? configRoutes[routeName],
  settings: RouteSettings(name: routeName),
  ),
 );
 }
 
 //Pop page
 pop<T extends Object>([T result]) {
 navigator.pop(result);
 }
 
 //Push a page and remove all the pages below it
 pushNamedAndRemoveUntil(String newRouteName) {
 return navigator.pushNamedAndRemoveUntil(newRouteName, (Route<dynamic> route) => false);
 }
 
 //When calling Navigator.push Time callback
 @override
 void didPush(Route route, Route previousRoute) {
 super.didPush(route, previousRoute);
 if (_mRoutes == null) {
  _mRoutes = new List<Route>();
 }
 //It is dialog that filters and calls the push
 if (route is CupertinoPageRoute || route is MaterialPageRoute) {
  _mRoutes.add(route);
  routeObserver();
 }
 }
 
 //When calling Navigator.replace Time callback
 @override
 void didReplace({Route newRoute, Route oldRoute}) {
 super.didReplace();
 if (newRoute is CupertinoPageRoute || newRoute is MaterialPageRoute) {
  _mRoutes.remove(oldRoute);
  _mRoutes.add(newRoute);
  routeObserver();
 }
 }
 
 //When calling Navigator.pop Time callback
 @override
 void didPop(Route route, Route previousRoute) {
 super.didPop(route, previousRoute);
 if (route is CupertinoPageRoute || route is MaterialPageRoute) {
  _mRoutes.remove(route);
  routeObserver();
 }
 }
 
 @override
 void didRemove(Route removedRoute, Route oldRoute) {
 super.didRemove(removedRoute, oldRoute);
 if (removedRoute is CupertinoPageRoute || removedRoute is MaterialPageRoute) {
  _mRoutes.remove(removedRoute);
  routeObserver();
 }
 }
 
 void routeObserver() {
 Logutil. I (sname '& & routing stack &');
 LogUtil.i(sName, _mRoutes);
 Logutil. I (sname '& & current route &');
 LogUtil.i(sName, _mRoutes[_mRoutes.length - 1]);
 //The navigator of the current page, which is used to route jumps
 navigator = _mRoutes[_mRoutes.length - 1].navigator;
 streamController.sink.add(_mRoutes);
 }
}

4. How to use it

Token invalid jump

case 401:
  ToastUtil.showRed ('login invalid, please login again ');
  UserDao.clearAll();
  NavigatorManager.getInstance().pushNamedAndRemoveUntil(LoginPage.sName);
  break;

Click push to push jump

static jumpPage(String pageName, [WidgetBuilder builder]) {
  String currentRouteName = NavigatorManager.getInstance().currentRoute.settings.name;
  //If you are not logged in, do not jump
  if (NavigatorManager.getInstance().routes[0].settings.name != MainPage.sName) {
   return;
  }

  //Replace if it is already the current page
  if (currentRouteName == pageName) {
   NavigatorManager.getInstance().pushReplacementNamed(pageName, builder);
  } else {
   NavigatorManager.getInstance().pushNamed(pageName, builder);
  }
}

Monitor route change status bar color


class StatusBarUtil {
   static List<String> lightRouteNameList = [
    TaskhallPage.sName,
    //...
   ];
   static List darkRoutNameList = [
    SplashPage.sName,
    LoginPage.sName,
    MainPage.sName,
    //...
   ];
   
   static init() {
    NavigatorManager.getInstance().streamController.stream.listen((state) {
      setupStatusBar(state[state.length - 1]);
    })
   }
  
   setupStatusBar(Route currentRoute) {
    if (lightRouteNameList.contains(currentRoute.settings.name)) {
     setLight();
    } else if (darkRoutNameList.contains(currentRoute.settings.name)) {
     setDart();
    }
   }
}

It’s over. It’s over

summary

The above is the whole content of this article, I hope the content of this article has a certain reference learning value for your study or work, thank you for your support to developeppaer.