How to use WillPopScope in Flutter

Guide reading for Lao Meng: how to click the Back button twice to exit the App, how to realize multiple routes in the App, and how to realize the Back button only to exit the specified page will be shown in this article.

WillPopScope

WillPopScope is used to process whether to leave the current page or not. There are many ways to leave the current page in the Flutter, such as the return button on the AppBar and Cupertino NavigationBar. Clicking will return to the previous page. Clicking the entity (virtual) return button on the Android phone will also return to the previous page. This function may be particularly easy for iOS programmers to ignore Slightly.

We will use WillPopScope in the following cases:

  1. You need to ask the user if you want to exit.
  2. There are multiple navigators in the App. What you want is to let one of them exit, not the Navigator at the bottom of Widget tree.

Ask users if they want to exit

Click the back button on the first page of Android App. By default, the current activity will be closed and returned to the desktop. We hope to pop up a dialog box or give a prompt "click again to exit" at this time to avoid the user's misoperation.

WillPopScope(
    onWillPop: () async => showDialog(
        context: context,
        builder: (context) =>
            AlertDialog(title: Text('Are you sure you want to quit?'), actions: <Widget>[
              RaisedButton(
                  child: Text('sign out'),
                  onPressed: () => Navigator.of(context).pop(true)),
              RaisedButton(
                  child: Text('cancel'),
                  onPressed: () => Navigator.of(context).pop(false)),
            ])),
    child: Container(
      alignment: Alignment.center,
      child: Text('Click the back button to ask if you want to exit.'),
    ))

We can also make the effect as quick click twice to exit:

DateTime _lastQuitTime;
WillPopScope(
    onWillPop: () async {
      if (_lastQuitTime == null ||
          DateTime.now().difference(_lastQuitTime).inSeconds > 1) {
        print('Press again Back Button exit');
        Scaffold.of(context)
            .showSnackBar(SnackBar(content: Text('Press again Back Button exit')));
        _lastQuitTime = DateTime.now();
        return false;
      } else {
        print('sign out');
        Navigator.of(context).pop(true);
        return true;
      }
    },
    child: Container(
      alignment: Alignment.center,
      child: Text('Click the back button to ask if you want to exit.'),
    ))

Multiple navigators in App

Our App usually has a Navigator under MaterialApp and CupertinoApp, so by default, calling Navigator.pop or Navigator.push is to operate this Navigator. However, in some cases, we want to have our own Navigator, such as the following scenarios:

  • There is a resident bar at the bottom of the page, which displays the content. This resident bar requires its own Navigator.
  • When using the components of TabView, BottomNavigationBar, and Cupertino TabView, you want to have multiple tabs, but each Tab has its own navigation behavior. At this time, you need to add a Navigator to each Tab.

Home page:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  GlobalKey<NavigatorState> _key = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WillPopScope(
          onWillPop: () async {
            if (_key.currentState.canPop()) {
              _key.currentState.pop();
              return false;
            }
            return true;
          },
          child: Column(
            children: <Widget>[
              Expanded(
                child: Navigator(
                  key: _key,
                  onGenerateRoute: (RouteSettings settings) =>
                      MaterialPageRoute(builder: (context) {
                    return OnePage();
                  }),
                ),
              ),
              Container(
                height: 50,
                color: Colors.blue,
                alignment: Alignment.center,
                child: Text('bottom Bar'),
              )
            ],
          )),
    );
  }
}

First page:

class OnePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: RaisedButton(
            child: Text('Go to the next page'),
            onPressed: () {
              Navigator.push(context, MaterialPageRoute(builder: (context) {
                return TwoPage();
              }));
            },
          ),
        ),
      ),
    );
  }
}

Second page:

class TwoPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: Text('This is the second page'),
        ),
      ),
    );
  }
}

The same principle applies to TabView, BottomNavigationBar and Cupertino TabView. You only need to add a Navigator to each Tab and do not forget to specify a key.

communication

Blog address of Lao Meng Flutter (nearly 200 controls usage): http://laomengit.com

Welcome to Flutter exchange group (WeChat: laomengit) and official account [Lao Meng Flutter]:

Keywords: Mobile Android iOS

Added by Tranquilraven on Wed, 13 May 2020 03:49:00 +0300