当同时向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();
}
}
注:经过编辑,直接加入了代码。
当把
WidgetsBinding.instance.addPostFrameCallback()
两者之间 Navigator.push()
调用,FirstWidget被正确注册,而 didPushNext FirstWidget
回调被触发。
参见 翩翩问题#55949 更多细节。