double press back button to exit app
press back button again to exit the app

Hi Guys, Welcome to Proto Coders Point.

There are some flutter app that has a feature like app exit when user double press back button.

When back buton is pressed for first time a toast message or a snackbar popup can be shown to user sayingpress back button again to exit the app, Then immediatly in a seconds, if back button is pressed again, your flutter app will Exit.

So, In this flutter tutorial, we will learn how to implement “Press back button to exit” in flutter, also called as double back press to exit app.

We will make use of WillPopScope Widget to acheive this.

What is WillPopScope Widget

WillPopScope widget is used to detect when user press the back button.

So, whenever a user press back button, you will get a callback at onWillPop function, which return Future value i.e. Either True or False.

If it returned value is true, the screen will be popped and exit the .

Syntax:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
WillPopScope(
onWillPop: () async{
//callback function when back button is pressed
},
child: Scaffold(),
);
WillPopScope( onWillPop: () async{ //callback function when back button is pressed }, child: Scaffold(), );
WillPopScope(
      onWillPop: () async{
          //callback function when back button is pressed
      },
      child: Scaffold(),
);

Here if onWillPop() async function return true, then you flutter app will get exited.


How to Implement Double back press to exit in flutter

1. Simply Wrap your Scaffold Widget with WillPopScope Widget.

Snippet Example

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
WillPopScope(
onWillPop: () async{
//callback function when back button is pressed
},
child: Scaffold(),
);
WillPopScope( onWillPop: () async{ //callback function when back button is pressed }, child: Scaffold(), );
WillPopScope(
      onWillPop: () async{
          //callback function when back button is pressed
      },
      child: Scaffold(),
);

so now whenever your flutter app user press back button, WillPopScope will detect it and send the a callback to onWillPop() function in it.

Note: if onWillPop return true that means it will close the screen i.e. back press exit the app.

2. How to implement back press again to exit flutter app

To implement press back button again in flutter, we will make use of DateTime.now(), DateTime.now() will return current time.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
DateTime pre_backpress = DateTime.now();
DateTime pre_backpress = DateTime.now();
DateTime pre_backpress = DateTime.now();

So, We will create 2 time variable & find the time gap between both the time vairable.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
final timegap = DateTime.now().difference(pre_backpress);
print('$timegap');
final timegap = DateTime.now().difference(pre_backpress); print('$timegap');
final timegap = DateTime.now().difference(pre_backpress);

print('$timegap');

The above code will return the timegap between them.

Now, let’s initialize booleon variable, where will check if timegap duration is greater then 2 seconds.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
final cantExit = timegap >= Duration(seconds: 2);
final cantExit = timegap >= Duration(seconds: 2);
final cantExit = timegap >= Duration(seconds: 2);

if timegap is more than 2 second we will set ‘cantExit’ variable to true.

if cantExit = true; that means we can’t exit app, so will show snackbar to user saying ‘‘Press back button again to Exit app”

if cantExit = false; i.e. Timegap between second back press is less then 2 second, that means user can exit the app.

Complete Snippet code of onWillPop

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
onWillPop: () async{
final timegap = DateTime.now().difference(pre_backpress);
final cantExit = timegap >= Duration(seconds: 2);
pre_backpress = DateTime.now();
if(cantExit){
//show snackbar
final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),);
ScaffoldMessenger.of(context).showSnackBar(snack);
return false; // false will do nothing when back press
}else{
return true; // true will exit the app
}
},
onWillPop: () async{ final timegap = DateTime.now().difference(pre_backpress); final cantExit = timegap >= Duration(seconds: 2); pre_backpress = DateTime.now(); if(cantExit){ //show snackbar final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),); ScaffoldMessenger.of(context).showSnackBar(snack); return false; // false will do nothing when back press }else{ return true; // true will exit the app } },
onWillPop: () async{

           final timegap = DateTime.now().difference(pre_backpress);

           final cantExit = timegap >= Duration(seconds: 2);

           pre_backpress = DateTime.now();

           if(cantExit){
             //show snackbar
             final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),);

             ScaffoldMessenger.of(context).showSnackBar(snack);

             return false; // false will do nothing when back press
           }else{
             return true;   // true will exit the app
           }

      },

Complete Source Code – Implement double back press to exit flutter app

main.dart

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import 'package:flutter/material.dart';
import 'package:passing_data/FruitDataModel.dart';
import 'package:passing_data/FruitDetail.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class HomePage extends StatelessWidget {
DateTime pre_backpress = DateTime.now();
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async{
final timegap = DateTime.now().difference(pre_backpress);
final cantExit = timegap >= Duration(seconds: 2);
pre_backpress = DateTime.now();
if(cantExit){
//show snackbar
final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),);
ScaffoldMessenger.of(context).showSnackBar(snack);
return false;
}else{
return true;
}
},
child: Scaffold(
body: Container(),
),
);
}
}
import 'package:flutter/material.dart'; import 'package:passing_data/FruitDataModel.dart'; import 'package:passing_data/FruitDetail.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: HomePage(), debugShowCheckedModeBanner: false, ); } } class HomePage extends StatelessWidget { DateTime pre_backpress = DateTime.now(); @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async{ final timegap = DateTime.now().difference(pre_backpress); final cantExit = timegap >= Duration(seconds: 2); pre_backpress = DateTime.now(); if(cantExit){ //show snackbar final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),); ScaffoldMessenger.of(context).showSnackBar(snack); return false; }else{ return true; } }, child: Scaffold( body: Container(), ), ); } }
import 'package:flutter/material.dart';
import 'package:passing_data/FruitDataModel.dart';
import 'package:passing_data/FruitDetail.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class HomePage extends StatelessWidget {
  
  DateTime pre_backpress = DateTime.now();
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async{
        final timegap = DateTime.now().difference(pre_backpress);

        final cantExit = timegap >= Duration(seconds: 2);

        pre_backpress = DateTime.now();

        if(cantExit){
          //show snackbar
          final snack = SnackBar(content: Text('Press Back button again to Exit'),duration: Duration(seconds: 2),);

          ScaffoldMessenger.of(context).showSnackBar(snack);
          return false;
        }else{
          return true;
        }
      },
      child: Scaffold(
        body: Container(),
      ),
    );
  }
}