Catching Back Button Presses on Android using Navigator 2.0

A Flutter Case Study

Lee Phillips
CodeX
4 min readDec 28, 2021

--

Welcome to the first in a new series of articles on Flutter. I have recently started browsing StackOverflow for Flutter related that I might be able to answer in an effort to help the community of budding Flutter enthusiasts. Every now and then, I come across a question that I feel warrants an article explaining the problem and solution, and perhaps a few details as to why the issue arises to begin with. I have dubbed these articles Case Studies, and I look forward into digging into the intriguing, obscure, or far-too-common issues that I come across. So without further ado, let’s dive into our first case study.

If you found this article worthy of a read from the title, then you have undoubtedly had experience catching back button presses on Android in Flutter pre-Navigator 2.0, but here’s a little refresher. We simply wrap our widget tree in a WillPopScope widget and provide an onWillPop callback. Here is an example that catches the back button press and provides an AlertDialog to confirm app exit.

As you can see, the user’s input in the AlertDialog will tell us whether they actually want to leave the app, and we can pass that result along to the WillPopScope widget.

If you’ve tried this approach while using Navigator 2.0, then you’ve discovered that WillPopScope no longer catches back button presses. This is because with Navigator 2.0, RouterDelegate's popRoute method is responsible for handling requests from the operating system to pop the current route (back button presses), and we can see in the method’s documentation:

The method should return a boolean [Future] to indicate whether this delegate handles the request. Returning false will cause the entire app to be popped.

The implementation by design pops the entire app immediately upon a press of the back button. Therefore, we must override it when extending the RouterDelegate class and handle back button presses according to our needs.

If you do not need back button presses to navigate backwards in your app and need it to present the exit app dialog at all times, you may omit the first if statement.

NOTE: You may have noticed that the results from the dialog are reversed in the two approaches. This is because when using WillPopScope, we are telling the widget if it should pop the scope from the Navigator (true = pop, false = don’t pop). When using Navigator 2.0, we are telling the Router whether or not we have handled the request (true = handled, false = not handled). When we report that we have not handled it ourselves, the Router handles it by exiting the app.

That’s all there is to it. By moving your logic from WillPopScope's onWillPop callback, to RouterDelegate's popRoute method, you can easily handle back button presses while using Navigator 2.0.

If you would like a deeper dive into Navigator 2.0 with an in-depth tutorial on converting an app to Navigator 2.0, check out my 3 part series starting with A Simpler Guide to Flutter Navigator 2.0: Part I.

Thank you for reading! If you found this article helpful and would like to read more case studies, please clap and follow. Happy coding!

--

--

Lee Phillips
CodeX

Software engineer. Flutter fanatic. I am here to share knowledge & inspire others to create great experiences.