I am trying to implement Navigator 2.0 method. The only thing I can't make to work is the back button presses. When I press the back button, the app just exits and not going to the previous page. I tried the WillPopPage widget but back button bypassing it.
here is a sample code that doesn't work on back presses.
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(TestApp());
}
class TestApp extends StatefulWidget {
@override
_TestAppState createState() => _TestAppState();
}
class _TestAppState extends State<TestApp> {
bool go = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Navigator(
pages: [
// page 1
MaterialPage(
child: W1(onTapped: () {
setState(() => go = true);
}),
),
// page 2
if (go) MaterialPage(child: W2()),
],
onPopPage: (route, result) {
if (!route.didPop(result)) return false;
go = false;
return true;
},
),
);
}
}
class W1 extends StatelessWidget {
final void Function() onTapped;
const W1({Key key, this.onTapped}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FlatButton(
onPressed: onTapped,
child: Text("Go to second"),
),
),
);
}
}
class W2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("pressing the back button is exiting the app.."),
),
);
}
}
I have already written a lot of code with this approach, so I can't go back to the imperative navigation anymore. How to handle the back pres with this approach?
The WillPopScope widget comes with the Flutter framework. It gives us control over the back button action, allowing the current page to go back to the previous one if it meets certain requirements. This is achieved using a callback, which the widget takes in as one of its parameters.
The basic way — push and pop The Navigator behaves like a stack, so the most simple way is to push a new page onto it when you want to navigate to it and to pop a page if you want to go back.
This is not possible with Navigator 2.0 without extending RouterDelegate
. A system back button press is handled by RouteDelegate
's popRoute
method. According to the docs:
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 default implementation always returns false. Therefore, you must override it to handle system back button presses.
UPDATE
I have published an article presenting a quick and easy-to-understand guide to using Navigator 2.0. You can find it here.
You'll have to use 'WillPopScope' https://api.flutter.dev/flutter/widgets/WillPopScope-class.html
Example
Future<bool> _willPopScopeCall() async {
// code to show toast or modal
return true; // return true to exit app or return false to cancel exit
}
//wrap your scaffold with WillPopScope
WillPopScope(child: new Scaffold(), onWillPop: _willPopScopeCall);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With