1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:ui';
6
7import 'package:flutter/material.dart';
8import 'package:flutter/services.dart';
9
10/// Flutter code sample for [ServicesBinding.handleRequestAppExit].
11
12void main() {
13 runApp(const ApplicationExitExample());
14}
15
16class ApplicationExitExample extends StatelessWidget {
17 const ApplicationExitExample({super.key});
18
19 @override
20 Widget build(BuildContext context) {
21 return const MaterialApp(home: Scaffold(body: Body()));
22 }
23}
24
25class Body extends StatefulWidget {
26 const Body({super.key});
27
28 @override
29 State<Body> createState() => _BodyState();
30}
31
32class _BodyState extends State<Body> with WidgetsBindingObserver {
33 bool _shouldExit = false;
34 String lastResponse = 'No exit requested yet';
35
36 @override
37 void initState() {
38 super.initState();
39 WidgetsBinding.instance.addObserver(this);
40 }
41
42 @override
43 void dispose() {
44 WidgetsBinding.instance.removeObserver(this);
45 super.dispose();
46 }
47
48 Future<void> _quit() async {
49 final AppExitType exitType = _shouldExit ? AppExitType.required : AppExitType.cancelable;
50 setState(() {
51 lastResponse = 'App requesting ${exitType.name} exit';
52 });
53 await ServicesBinding.instance.exitApplication(exitType);
54 }
55
56 @override
57 Future<AppExitResponse> didRequestAppExit() async {
58 final AppExitResponse response = _shouldExit ? AppExitResponse.exit : AppExitResponse.cancel;
59 setState(() {
60 lastResponse = 'App responded ${response.name} to exit request';
61 });
62 return response;
63 }
64
65 void _radioChanged(bool? value) {
66 value ??= true;
67 if (_shouldExit == value) {
68 return;
69 }
70 setState(() {
71 _shouldExit = value!;
72 });
73 }
74
75 @override
76 Widget build(BuildContext context) {
77 return Center(
78 child: SizedBox(
79 width: 300,
80 child: Column(
81 mainAxisSize: MainAxisSize.min,
82 children: <Widget>[
83 RadioListTile<bool>(
84 title: const Text('Do Not Allow Exit'),
85 groupValue: _shouldExit,
86 value: false,
87 onChanged: _radioChanged,
88 ),
89 RadioListTile<bool>(
90 title: const Text('Allow Exit'),
91 groupValue: _shouldExit,
92 value: true,
93 onChanged: _radioChanged,
94 ),
95 const SizedBox(height: 30),
96 ElevatedButton(onPressed: _quit, child: const Text('Quit')),
97 const SizedBox(height: 30),
98 Text(lastResponse),
99 ],
100 ),
101 ),
102 );
103 }
104}
105