Home > Mobile >  Flutter back button
Flutter back button

Time:11-12

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?

CodePudding user response:

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(),
      );
  }
}

CodePudding user response:

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

  • Related