0

I have added following code to my main screen in order to exit app after 2 times back button taps

Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: () async {
      final timeGap = DateTime.now().difference(preBackpress);
      final cantExit = timeGap >= const Duration(seconds: 2);
      preBackpress = DateTime.now();
      if(cantExit){
        const 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(....)
  );
}

But what I get instead is that when I hit back button it goes all the steps back to every single screen user has been visited.

The reason I added WillPopScope above was to avoid going back to visited screen and just close the app but it seems still doesn't help.

My question is: How do I exit app (when in main screen back button is tapped) without going back to visited screens?

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
mafortis
  • 6,750
  • 23
  • 130
  • 288

2 Answers2

1

Maybe this is not the same as your code. but I have code to close apps as you want

class ExitController extends StatefulWidget {
  @override
  _ExitControllerState createState() => _ExitControllerState();
}

class _ExitControllerState extends State<ExitController> {
  static const snackBarDuration = Duration(milliseconds: 2000);
  // set how long the snackbar appears
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  DateTime? backButtonPressTime;

  final snackBar = SnackBar(
    behavior: SnackBarBehavior.floating,
    // margin: EdgeInsets.fromLTRB(75, 0, 75, 250),
    // add margin so that the snackbar is not at the bottom
    duration: snackBarDuration,
    backgroundColor: Colors.black87,
    content: Text('Press Again to Exit',
        textAlign: TextAlign.center,
        style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12)),
  );

  Future<bool> onWillPop() async {
    DateTime currentTime = DateTime.now();

    bool backButtonCondition =
        backButtonPressTime == null ||
            currentTime.difference(backButtonPressTime!) > snackBarDuration;

    if (backButtonCondition) {
      backButtonPressTime = currentTime;
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
      return false;
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      body: WillPopScope(
        onWillPop: onWillPop,
        child: yourPageClass(),
      ),
    );
  }
}

The snackbar will appear for 2000 milliseconds and during that time if the user press the back button again, the application will exit

Note to call ExitController class in main.dart, and wrapping your all structure(navigation class/page class/etc) with this ExitController class. Example:

main.dart

import 'package:flutter/material.dart';
import 'package:app_name/structure.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ExitController(),
      );
  }
}
Septian Dika
  • 446
  • 5
  • 17
  • It still does the same (going to previous screens) the only difference is that it needs 2 times back button to show previous screens! :/ – mafortis Nov 12 '21 at 04:26
  • Where did you put the WillPopScope? Did you put WillPopScope as parent and above all classes? – Septian Dika Nov 12 '21 at 05:36
  • Yes, same structure as your sample code – mafortis Nov 12 '21 at 05:41
  • Does your question mean when the user has moved to the second page from the first-page, users can close the application even though they are on the second-page? – Septian Dika Nov 12 '21 at 05:49
  • I'm sure this problem occurs because of the class structure that you create or because of the way you wrap your class structure. not because of the code you attached. – Septian Dika Nov 12 '21 at 05:54
  • no, I mean: `page one ->page two->page one->close` currently is like: `page one->page two->page one->page two->page one->close` – mafortis Nov 12 '21 at 06:03
  • When I back to page one from any page, it should be closed not to be back to those pages again – mafortis Nov 12 '21 at 06:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239144/discussion-between-septian-dika-and-mafortis). – Septian Dika Nov 12 '21 at 06:07
  • Can I assume that you are not using the navigation bar?. If yes. Please update your question and attach the code of first page and second page. – Septian Dika Nov 12 '21 at 06:10
0
WillPopScope(
        onWillPop: () async {
          return await showDialog(context: ctx, builder: (_) => exitAlertDialog(_));
        },
        child: GestureDetector(onTap: () => FocusScope.of(ctx).unfocus(), child: widget));

Widget exitAlertDialog(BuildContext context) {
  return AlertDialog(
    backgroundColor: plColor2,
    content: Text('Are you sure you want to exit?'),
    actions: <Widget>[
      TextButton(child: Text('No'), onPressed: () => Navigator.of(context).pop(false)),
      TextButton(child: Text('Yes, exit'), onPressed: () => SystemNavigator.pop())
    ],
  );
}

or you can use showsnackbar as your need

Dharman
  • 30,962
  • 25
  • 85
  • 135