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 | |
5 | import 'framework.dart'; |
6 | import 'navigator.dart'; |
7 | import 'routes.dart'; |
8 | |
9 | /// Registers a callback to veto attempts by the user to dismiss the enclosing |
10 | /// [ModalRoute]. |
11 | /// |
12 | /// See also: |
13 | /// |
14 | /// * [ModalRoute.addScopedWillPopCallback] and [ModalRoute.removeScopedWillPopCallback], |
15 | /// which this widget uses to register and unregister [onWillPop]. |
16 | /// * [Form], which provides an `onWillPop` callback that enables the form |
17 | /// to veto a `pop` initiated by the app's back button. |
18 | @Deprecated( |
19 | 'Use PopScope instead. ' |
20 | 'This feature was deprecated after v3.12.0-1.0.pre.' , |
21 | ) |
22 | class WillPopScope extends StatefulWidget { |
23 | /// Creates a widget that registers a callback to veto attempts by the user to |
24 | /// dismiss the enclosing [ModalRoute]. |
25 | @Deprecated( |
26 | 'Use PopScope instead. ' |
27 | 'This feature was deprecated after v3.12.0-1.0.pre.' , |
28 | ) |
29 | const WillPopScope({ |
30 | super.key, |
31 | required this.child, |
32 | required this.onWillPop, |
33 | }); |
34 | |
35 | /// The widget below this widget in the tree. |
36 | /// |
37 | /// {@macro flutter.widgets.ProxyWidget.child} |
38 | final Widget child; |
39 | |
40 | /// Called to veto attempts by the user to dismiss the enclosing [ModalRoute]. |
41 | /// |
42 | /// If the callback returns a Future that resolves to false, the enclosing |
43 | /// route will not be popped. |
44 | final WillPopCallback? onWillPop; |
45 | |
46 | @override |
47 | State<WillPopScope> createState() => _WillPopScopeState(); |
48 | } |
49 | |
50 | class _WillPopScopeState extends State<WillPopScope> { |
51 | ModalRoute<dynamic>? _route; |
52 | |
53 | @override |
54 | void didChangeDependencies() { |
55 | super.didChangeDependencies(); |
56 | if (widget.onWillPop != null) { |
57 | _route?.removeScopedWillPopCallback(widget.onWillPop!); |
58 | } |
59 | _route = ModalRoute.of(context); |
60 | if (widget.onWillPop != null) { |
61 | _route?.addScopedWillPopCallback(widget.onWillPop!); |
62 | } |
63 | } |
64 | |
65 | @override |
66 | void didUpdateWidget(WillPopScope oldWidget) { |
67 | super.didUpdateWidget(oldWidget); |
68 | if (widget.onWillPop != oldWidget.onWillPop && _route != null) { |
69 | if (oldWidget.onWillPop != null) { |
70 | _route!.removeScopedWillPopCallback(oldWidget.onWillPop!); |
71 | } |
72 | if (widget.onWillPop != null) { |
73 | _route!.addScopedWillPopCallback(widget.onWillPop!); |
74 | } |
75 | } |
76 | } |
77 | |
78 | @override |
79 | void dispose() { |
80 | if (widget.onWillPop != null) { |
81 | _route?.removeScopedWillPopCallback(widget.onWillPop!); |
82 | } |
83 | super.dispose(); |
84 | } |
85 | |
86 | @override |
87 | Widget build(BuildContext context) => widget.child; |
88 | } |
89 | |