首页 > 解决方案 > 如何在 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(),
      ),
    );
  }
}

标签: androidflutterdialogflutter-layout

解决方案


你可以通过修改你BottomNavigationBaronTap.

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

推荐阅读