一次推送两条路线时,不会调用 RouteAware didPushNext

RouteAware didPushNext is not called when pushing two routes at once

同时推送两条路由到Navigator并使用RouteAware获取时 关于当前状态的更新,第一条路线的 didPopNext() 不是 打电话。

似乎调用了 RouteObserver.didPush()(会调用 didPushNext) 在调用 FirstWiget 的 didChangeDependencies() 之前的两条路线 我订阅了 routeObserver。

当一个接一个地推送路由并等待小部件出现时,这是我所期望和得到的:

I/flutter (30927): Navigator.push(FirstWidget)
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didPush FirstWidget
I/flutter (30927): build FirstWidget
I/flutter (30927): Navigator.push(SecondWidget)
I/flutter (30927): didPushNext FirstWidget
I/flutter (30927): didChangeDependencies SecondWidget
I/flutter (30927): didPush SecondWidget
I/flutter (30927): build SecondWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): build FirstWidget

同时按下时:

I/flutter (30927): Navigator.push(FirstWidget)
I/flutter (30927): Navigator.push(SecondWidget)
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): didPush FirstWidget
I/flutter (30927): build FirstWidget
I/flutter (30927): didChangeDependencies SecondWidget
I/flutter (30927): didPush SecondWidget
I/flutter (30927): build SecondWidget
I/flutter (30927): didChangeDependencies FirstWidget
I/flutter (30927): build FirstWidget

这是 运行 示例:

import 'package:flutter/material.dart';

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

void main() {
  runApp(MaterialApp(
    title: 'Navigation Test',
    home: StartWidget(),
    navigatorObservers: <NavigatorObserver>[routeObserver],
  ));
}

class StartWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Start'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('Open both routes'),
              onPressed: () {
                print("Navigator.push(FirstWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => FirstWidget()),
                );
                print("Navigator.push(SecondWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondWidget()),
                );
              },
            ),
            RaisedButton(
              child: Text('Open FirstWidget'),
              onPressed: () {
                print("Navigator.push(FirstWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => FirstWidget()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

class FirstWidget extends StatefulWidget {
  @override
  _FirstWidgetState createState() => _FirstWidgetState();
}

class _FirstWidgetState extends RouteAwareState<FirstWidget> {
  Widget build(BuildContext context) {
    print("build $widget");
    return Scaffold(
      appBar: AppBar(
        title: Text('FirstWidget'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('Open SecondWidget'),
              onPressed: () {
                print("Navigator.push(SecondWidget)");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondWidget()),
                );
              },
            ),
            RaisedButton(
              child: Text('back'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

class SecondWidget extends StatefulWidget {
  @override
  _SecondWidgetState createState() => _SecondWidgetState();
}

class _SecondWidgetState extends RouteAwareState<SecondWidget> {
  @override
  Widget build(BuildContext context) {
    print("build $widget");
    return Scaffold(
      appBar: AppBar(
        title: Text('SecondWidget'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('back'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

abstract class RouteAwareState<T extends StatefulWidget> extends State<T>
    with RouteAware {
  @override
  void didChangeDependencies() {
    print("didChangeDependencies $widget");
    routeObserver.subscribe(this, ModalRoute.of(context)); //Subscribe it here
    super.didChangeDependencies();
  }

  @override
  void didPush() {
    print('didPush $widget');
  }

  @override
  void didPopNext() {
    print('didPopNext $widget');
  }

  @override
  void didPop() {
    print('didPop $widget');
  }

  @override
  void didPushNext() {
    print('didPushNext $widget');
  }

  @override
  void dispose() {
    print("dispose $widget");
    routeObserver.unsubscribe(this);
    super.dispose();
  }
}

注意:编辑后直接包含代码。

放置时

WidgetsBinding.instance.addPostFrameCallback()

在两次 Navigator.push() 调用之间,正确注册了 FirstWidget 并触发了 didPushNext FirstWidget 回调。

有关详细信息,请参阅 flutter issue #55949