android - 如何在 Flutter 中离开页面前显示确认对话框
问题描述
我有一个包含三个不同页面的应用程序。要在页面之间导航,我使用底部导航。其中一个页面包含一个表格。在离开表单页面之前,我想显示一个确认对话框。我知道我可以用 WillPopScope 拦截设备的后退按钮。这完美地工作。但是当我通过底部导航离开页面时,不会触发 WillPopScope。
我也尝试过使用 WidgetsBindingObserver,但是 didPopRoute 和 didPushRoute 都不会被触发。
有什么想法我能做什么?
我的表单页面:
class TodayTimeRecordFormState extends State<TodayTimeRecordForm> with WidgetsBindingObserver{
final formKey = GlobalKey<FormState>();
TodayTimeRecordFormState();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Future<bool> didPopRoute() {
//never called
_onWillPop();
}
@override
Future<bool> didPushRoute(String route){
//never called
_onWillPop();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
// called when the device back button is pressed.
onWillPop: _onWillPop,
child: Scaffold(...));
}
Future<bool> _onWillPop() {
return showDialog(
context: context,
child: new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Unsaved data will be lost.'),
actions: <Widget>[
new FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
new FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
);
}
}
包含底部导航的页面:
const List<Navigation> allNavigationItems = <Navigation>[
Navigation('Form', Icons.home, Colors.orange),
Navigation('Page2', Icons.work_off, Colors.orange),
Navigation('Page3', Icons.poll, Colors.orange)
];
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HomePageState();
}
}
class HomePageState extends State<HomePage> {
int selectedTab = 0;
final pageOptions = [
TodayTimeRecordForm(),
Page2(),
Page3(),
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppConfig.instance.values.title),
),
body: pageOptions[selectedTab],
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedTab,
unselectedItemColor: Colors.grey,
showUnselectedLabels: true,
selectedItemColor: Colors.amber[800],
onTap: (int index) {
setState(() {
selectedTab = index;
});
},
items: allNavigationItems.map((Navigation navigationItem) {
return BottomNavigationBarItem(
icon: Icon(navigationItem.icon),
backgroundColor: Colors.white,
label: navigationItem.title);
}).toList(),
),
);
}
}
解决方案
你可以通过修改你BottomNavigationBar
的onTap
.
onTap: (int index) {
if (selectedTab == 0 && index != 0){
// If the current tab is the first tab (the form tab)
showDialog(
context: context,
child: new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Unsaved data will be lost.'),
actions: <Widget>[
new FlatButton(
onPressed: () => Navigator.pop(context), // Closes the dialog
child: new Text('No'),
),
new FlatButton(
onPressed: () {
setState(()=>selectedTab = index); // Changes the tab
Navigator.pop(context); // Closes the dialog
},
child: new Text('Yes'),
),
],
),
);
} else {
// If the current tab isn't the form tab
setState(()=>selectedTab = index);
}
},
推荐阅读
- android - Hilt ClassCastException:无法将 ViewComponentManager$FragmentContextWrapper 强制转换为 AppCompatActivity
- python - Python - 如何将 Ping 结果输出到 Pandas DataFrame 对象
- javascript - PHP echo javascript在if语句中不起作用
- r - 查找键:R列表中最小值的值对
- git - 如何在我的 Travis Build 中回显当前的 git 分支
- node.js - 如何使用 koa-graphql 设置 graphql-upload?
- java - 即使我安装了 JRE,也无法打开 .jnlp 文件
- c# - 将带有 3 个选项的性别放入数组的元素中
- c# - 如何使用文本框过滤我的 datagirdview?
- python - 联合 Tensorflow 内存——使单个 GPU 过载