同时推送两个路由时,不调用RouteAware didPushNext。

问题描述 投票:2回答:1

当同时向Navigator推送两条路由,并使用RouteAware获取当前状态的更新时,第一条路由的didPopNext()没有被调用。

似乎RouteObserver.didPush()(会调用didPushNext)在我订阅的RouteObserver的FirstWiget的didChangeDependencies()被调用之前,两个路由都被调用了。

这是我所期望的,也是我所得到的,当一个接一个地推送路由并等待widget出现时。

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();
  }
}

注:经过编辑,直接加入了代码。

flutter navigator
1个回答
0
投票

当把

WidgetsBinding.instance.addPostFrameCallback()

两者之间 Navigator.push() 调用,FirstWidget被正确注册,而 didPushNext FirstWidget 回调被触发。

参见 翩翩问题#55949 更多细节。

© www.soinside.com 2019 - 2024. All rights reserved.