When developing Flutter apps, there might be cases where we want to display a confirmation dialog when a user presses the back button. The purpose is to prevent accidentally leaving a screen (page), especially a screen with unsaved form data. A good solution for this is to wrap the screen that requires confirmation before leaving within a WillPopScope widget:
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
/* ... */
// Show the confirmation dialog
// Return "true" means "go back", return "false" means "stay here"
},
child: Scaffold(
/* ... */
));
}
For more clarity, see the example below.
Table of Contents
Example
The tiny app we are going to build has 2 screens:
- HomeScreen: Contains a button in the center of the screen that lets the user navigate to OtherScreen.
- OtherScreen: Contains nothing but an app bar with a back button. When the back button is pressed, a confirmation popup will show up. If the user selects “Yes”, he or she will go back to the HomeScreen. If the user selects “No”, they will stay here, and the popup will go away too.
Preview
The Complete Code
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: const HomeScreen());
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Kindacode.com'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => const OtherScreen()));
},
child: const Text('Navigate to OtherScreen'),
),
),
);
}
}
class OtherScreen extends StatelessWidget {
const OtherScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
bool willLeave = false;
// show the confirm dialog
await showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Are you sure want to leave?'),
actions: [
ElevatedButton(
onPressed: () {
willLeave = true;
Navigator.of(context).pop();
},
child: const Text('Yes')),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('No'))
],
));
return willLeave;
},
child: Scaffold(
appBar: AppBar(
title: const Text('Other Screen'),
),
body: const Center(),
));
}
}
Conclusion
We’ve examined a complete example of displaying a confirmation popup when the user presses the back button. If you’d like to learn more new and interesting things about Flutter, have a look at the following articles:
- Flutter & SQLite: CRUD Example
- Flutter: ValueListenableBuilder Example
- Working with Table in Flutter
- Using GetX (Get) for Navigation and Routing in Flutter
- Flutter: Bottom Sheet examples
- Flutter & Hive Database: CRUD Example
- Using Provider for State Management in Flutter
You can also check out our Flutter category page or Dart category page for the latest tutorials and examples.