Manab Gogoi
Manab Gogoi

Reputation: 59

how to exit the app if the device back button is pressed flutter

I want to display a dialog when the device back button is pressed.... if user press no then nothing will happens...... but if the user press yes then the application shall close..... I have tried willpopscope but it is not working......

Can anyone help me with this???

this is my main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:users_app/splashScreen/splash_screen.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();

  runApp(MyApp(
      child: MaterialApp(
    title: 'Drivers App',
    home: const MySplashScreen(),
    debugShowCheckedModeBanner: false,
  )));
}

class MyApp extends StatefulWidget {
  final Widget? child;

  MyApp({this.child});

  static void restartApp(BuildContext context) {
    context.findAncestorStateOfType<_MyAppState>()!.restartApp();
  }

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Key key = UniqueKey();

  void restartApp() {
    setState(() {
      key = UniqueKey();
    });
  }

  Future<bool?> showWarning(BuildContext context) async => showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
            title: const Text('DO you want to exit app?'),
            actions: [
              ElevatedButton(
                  onPressed: () => Navigator.of(context).pop(false),
                  child: Text('No')),
              ElevatedButton(
                  onPressed: () => Navigator.of(context).pop(true),
                  child: Text('Yes')),
            ],
          ));

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        print('Back Button Pressed');

        final shouldPop = await showWarning(context);

        return shouldPop ?? false;
      },
      child: KeyedSubtree(
        key: key,
        child: widget.child!,
      ),
    );
  }
}

Upvotes: 0

Views: 1885

Answers (3)

Xuuan Thuc
Xuuan Thuc

Reputation: 2521

Dialog don't show because you put it in main.dart. split it into 2 other files will work.

Try this:

main.dart

import 'dart:io';

import 'package:demo/home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'dialog.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: HomeScreen()
    );
  }
}

home.dart

import 'dart:io';

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}


void showConfirmDialog(BuildContext context, String errorMessage) async {
  await showDialog(
    context: context,
    barrierDismissible: true,
    builder: (BuildContext context) {
      return AlertDialog(
        backgroundColor: Theme.of(context).primaryColorLight,
        content: Text(
          errorMessage,
          style: TextStyle(
            fontSize: 15.0,
            fontWeight: FontWeight.w800,
            color: Theme.of(context).colorScheme.primary,
          ),
        ),
        actions: <Widget>[
          TextButton(
              child: Text(
                'Cancel',
                style: TextStyle(
                  color: Theme.of(context).colorScheme.primary,
                  fontWeight: FontWeight.w600,
                ),
              ),
              onPressed: () {

              }),
          TextButton(
            child: Text(
              'Accept',
              style: TextStyle(
                color: Theme.of(context).colorScheme.primary,
                fontWeight: FontWeight.w600,
              ),
            ),
            onPressed: () {
              exit(0);
            },
          ),
          const SizedBox(
            width: 5,
          ),
        ],
      );
    },
  );
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return  WillPopScope(
      onWillPop: () async {
        showConfirmDialog(context, 'Close the app?');
        return false;
      },
      child: Scaffold(
        body:  Container(
          color: Colors.blueGrey,
        ),
      ),
    );
  }
}

It will work!

Upvotes: 1

Dhruv Sakariya
Dhruv Sakariya

Reputation: 510

Widget build(BuildContext context) {
  return WillPopScope(
    child: /*Your scaffold widget*/
    onWillPop: () {
      return showDialog(
        context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text("Confirm Exit"),
        content: Text("Are you sure you want to exit app?"),
        actions: <Widget>[
          FlatButton(
            child: Text("Exit"),
            onPressed: () {
              SystemNavigator.pop();
            },
          ),
          FlatButton(
            child: Text("NO"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
            )
          ],
        );
      }
    );
    return Future.value(true);
  },

Upvotes: 3

Omar mgerbie
Omar mgerbie

Reputation: 86

you can simply use

SystemNavigator.pop();

and it'll close the app

Upvotes: 4

Related Questions