在 Flutter 中使用带有 WillPopScope 的嵌套导航器
Posted
技术标签:
【中文标题】在 Flutter 中使用带有 WillPopScope 的嵌套导航器【英文标题】:Use nested Navigator with WillPopScope in Flutter 【发布时间】:2019-11-15 08:12:50 【问题描述】:在我的应用程序中,我想要一个自定义导航(仅更改屏幕的一部分并保留我在其中所做的事情的历史记录)。 为此,我正在使用导航器,它可以很好地用于简单导航。 但是,我想处理 android 的后退按钮。 Flutter 中显然存在一个问题,这迫使我处理 Navigator 的父小部件中的后退按钮: https://github.com/flutter/flutter/issues/14083
因此,我需要在子项中检索我的 Navigator 实例并在其上调用 pop()。我正在尝试为此使用 GlobalKey。
我现在正在尝试让它工作一段时间,并制作了一个示例项目来测试它。 这是我的代码:
import 'package:flutter/material.dart';
void main()
runApp(MaterialApp(title: 'Navigation Basics', home: MainWidget()));
class MainWidget extends StatelessWidget
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
@override
Widget build(BuildContext context)
return SafeArea(
child: WillPopScope(
onWillPop: () => navigatorKey.currentState.maybePop(),
child: Scaffold(
body: Padding(
child: Column(
children: <Widget>[
Text("Toto"),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: RaisedButton(
child: Text('First'),
onPressed: ()
navigatorKey.currentState.pushNamed('/first');
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => SecondRoute()),
// );
,
)),
Expanded(
child: RaisedButton(
child: Text('Second'),
onPressed: ()
navigatorKey.currentState.pushNamed('/second');
,
))
],
),
Expanded(
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(color: Colors.red),
),
ConstrainedBox(
constraints: BoxConstraints.expand(),
child: _getNavigator()),
],
)),
],
),
padding: EdgeInsets.only(bottom: 50),
))));
Navigator _getNavigator()
return Navigator(
key: navigatorKey,
initialRoute: '/',
onGenerateRoute: (RouteSettings settings)
WidgetBuilder builder;
switch (settings.name)
case '/':
builder = (BuildContext _) => FirstRoute();
break;
case '/second':
builder = (BuildContext _) => SecondRoute();
break;
default:
throw new Exception('Invalid route: $settings.name');
return new MaterialPageRoute(builder: builder, settings: settings);
);
class FirstRoute extends StatelessWidget
@override
Widget build(BuildContext context)
return Container(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("GO TO FRAGMENT TWO"),
onPressed: () => Navigator.of(context).pushNamed("/second"),
)
],
),
decoration: BoxDecoration(color: Colors.green),
);
class SecondRoute extends StatelessWidget
@override
Widget build(BuildContext context)
return Container(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("GO TO FRAGMENT ONE"),
onPressed: () => Navigator.of(context).pop(),
)
],
),
decoration: BoxDecoration(color: Colors.blue),
);
但是,这并没有按我的意愿工作。默认的 Navigator 似乎仍在使用:打开 SecondRoute 并按下 Android 后退按钮后,它只是离开应用程序,而不是回到第一条路线。
我怎样才能实现我想要的?
【问题讨论】:
【参考方案1】:按照 onWillPop 的文档:
/// Called to veto attempts by the user to dismiss the enclosing [ModalRoute].
///
/// If the callback returns a Future that resolves to false, the enclosing
/// route will not be popped.
final WillPopCallback onWillPop;
您的处理程序应指示不应关闭封闭路由,因此返回 false 将解决您的问题。
将您的处理程序更改为此工作:
onWillPop: () async
navigatorKey.currentState.maybePop();
return false;
,
【讨论】:
在使用 WillPopScope 小部件时如何让 ios 中的“向后滑动”功能正常工作?以上是关于在 Flutter 中使用带有 WillPopScope 的嵌套导航器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Bloc Login Flutter 中使用带有身份验证的 NavigationDrawer 路由