简体   繁体   中英

How to update ChangeNotifier using NavigatorObserver

I want to update a ChangeNotifier whenever my Navigator changes routes.

I have created the following NavigatorObserver:

class NotifierNavigatorObserver extends NavigatorObserver {

  NotifierNavigatorObserver(this._changeNotifier);

  MyChangeNotifier _changeNotifier;

  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    _changeNotifier.setFirst(route.isFirst);
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    _changeNotifier.setFirst(previousRoute.isFirst);
  }
}

I attach the observer to the Navigator like this:

  @override
  Widget build(BuildContext context) {
    super.build(context);

    final NotifierNavigatorObserver navigatorObserver =
      NotifierNavigatorObserver(Provider.of<MyChangeNotifier>(context, listen: false));

    return Navigator(
        initialRoute: '/',
        onGenerateRoute: _routeFactory,
        onUnknownRoute: _getUnknownRoute,
        observers: [navigatorObserver]
    );
  }

When I run the application it works fine. I do however get the following error in the log:

I/flutter ( 9191): ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
I/flutter ( 9191): The following assertion was thrown while dispatching notifications for MyChangeNotifier:
I/flutter ( 9191): setState() or markNeedsBuild() called during build.
I/flutter ( 9191): This ChangeNotifierProvider<MyChangeNotifier> widget cannot be marked as needing to build because the
I/flutter ( 9191): framework is already in the process of building widgets.  A widget can be marked as needing to be
I/flutter ( 9191): built during the build phase only if one of its ancestors is currently building. This exception is
I/flutter ( 9191): allowed because the framework builds parent widgets before children, which means a dirty descendant
I/flutter ( 9191): will always be built. Otherwise, the framework might not visit this widget during this build phase.
I/flutter ( 9191): The widget on which setState() or markNeedsBuild() was called was:
I/flutter ( 9191):   ChangeNotifierProvider<MyChangeNotifier>
I/flutter ( 9191): The widget which was currently being built when the offending call was made was:
I/flutter ( 9191):   HomeRoot

What can I do to get rid of this error message?

didPush / didPop events are called while the widget tree is still building.

To prevent these exceptions, wrap your mutation into a Future.microtask:

  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    Future.microstask(() {
      _changeNotifier.setFirst(route.isFirst);
    });
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM