Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
66386255
Commit
66386255
authored
Feb 21, 2017
by
Adam Barth
Committed by
GitHub
Feb 21, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Factor WillPopScope out of Form (#8311)
This functionality is independently useful. Fixes #8293
parent
434d6c3f
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
119 additions
and
52 deletions
+119
-52
form.dart
packages/flutter/lib/src/widgets/form.dart
+8
-33
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+34
-19
will_pop_scope.dart
packages/flutter/lib/src/widgets/will_pop_scope.dart
+76
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
No files found.
packages/flutter/lib/src/widgets/form.dart
View file @
66386255
...
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
...
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
import
'framework.dart'
;
import
'framework.dart'
;
import
'routes.dart'
;
import
'routes.dart'
;
import
'will_pop_scope.dart'
;
/// An optional container for grouping together multiple form field widgets
/// An optional container for grouping together multiple form field widgets
/// (e.g. [Input] widgets).
/// (e.g. [Input] widgets).
...
@@ -64,35 +65,6 @@ class Form extends StatefulWidget {
...
@@ -64,35 +65,6 @@ class Form extends StatefulWidget {
class
FormState
extends
State
<
Form
>
{
class
FormState
extends
State
<
Form
>
{
int
_generation
=
0
;
int
_generation
=
0
;
Set
<
FormFieldState
<
dynamic
>>
_fields
=
new
Set
<
FormFieldState
<
dynamic
>>();
Set
<
FormFieldState
<
dynamic
>>
_fields
=
new
Set
<
FormFieldState
<
dynamic
>>();
ModalRoute
<
dynamic
>
_route
;
@override
void
dependenciesChanged
()
{
super
.
dependenciesChanged
();
if
(
_route
!=
null
&&
config
.
onWillPop
!=
null
)
_route
.
removeScopedWillPopCallback
(
config
.
onWillPop
);
_route
=
ModalRoute
.
of
(
context
);
if
(
_route
!=
null
&&
config
.
onWillPop
!=
null
)
_route
.
addScopedWillPopCallback
(
config
.
onWillPop
);
}
@override
void
didUpdateConfig
(
Form
oldConfig
)
{
assert
(
_route
==
ModalRoute
.
of
(
context
));
if
(
config
.
onWillPop
!=
oldConfig
.
onWillPop
&&
_route
!=
null
)
{
if
(
oldConfig
.
onWillPop
!=
null
)
_route
.
removeScopedWillPopCallback
(
oldConfig
.
onWillPop
);
if
(
config
.
onWillPop
!=
null
)
_route
.
addScopedWillPopCallback
(
config
.
onWillPop
);
}
}
@override
void
dispose
()
{
if
(
_route
!=
null
&&
config
.
onWillPop
!=
null
)
_route
.
removeScopedWillPopCallback
(
config
.
onWillPop
);
super
.
dispose
();
}
// Called when a form field has changed. This will cause all form fields
// Called when a form field has changed. This will cause all form fields
// to rebuild, useful if form fields have interdependencies.
// to rebuild, useful if form fields have interdependencies.
...
@@ -114,10 +86,13 @@ class FormState extends State<Form> {
...
@@ -114,10 +86,13 @@ class FormState extends State<Form> {
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
if
(
config
.
autovalidate
)
if
(
config
.
autovalidate
)
_validate
();
_validate
();
return
new
_FormScope
(
return
new
WillPopScope
(
onWillPop:
config
.
onWillPop
,
child:
new
_FormScope
(
formState:
this
,
formState:
this
,
generation:
_generation
,
generation:
_generation
,
child:
config
.
child
child:
config
.
child
,
),
);
);
}
}
...
...
packages/flutter/lib/src/widgets/routes.dart
View file @
66386255
...
@@ -688,10 +688,29 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
...
@@ -688,10 +688,29 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// Enables this route to veto attempts by the user to dismiss it.
/// Enables this route to veto attempts by the user to dismiss it.
///
///
/// This callback is typically added by a stateful descendant of the modal route.
/// This callback is typically added using a [WillPopScope] widget. That
/// A stateful widget shown in a modal route, like the child passed to
/// widget finds the enclosing [ModalRoute] and uses this function to register
/// [showDialog], can look up its modal route and then add a callback in its
/// this callback:
/// `dependenciesChanged` method:
///
/// ```dart
/// Widget build(BuildContext context) {
/// return new WillPopScope(
/// onWillPop: askTheUserIfTheyAreSure,
/// child: ...,
/// );
/// }
/// ```
///
/// This callback runs asynchronously and it's possible that it will be called
/// after its route has been disposed. The callback should check [mounted]
/// before doing anything.
///
/// A typical application of this callback would be to warn the user about
/// unsaved [Form] data if the user attempts to back out of the form. In that
/// case, use the [Form.onWillPop] property to register the callback.
///
/// To register a callback manually, look up the enclosing [ModalRoute] in a
/// [State.dependenciesChanged] callback:
///
///
/// ```dart
/// ```dart
/// ModalRoute<dynamic> _route;
/// ModalRoute<dynamic> _route;
...
@@ -705,28 +724,24 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
...
@@ -705,28 +724,24 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// }
/// }
/// ```
/// ```
///
///
/// A typical application of this callback would be to warn the user about
/// If you register a callback manually, be sure to remove the callback with
/// unsaved [Form] data if the user attempts to back out of the form.
/// [removeScopedWillPopCallback] by the time the widget has been disposed. A
///
/// stateful widget can do this in its dispose method (continuing the previous
/// This callback runs asynchronously and it's possible that it will be called
/// example):
/// after its route has been disposed. The callback should check [mounted] before
/// doing anything.
///
/// A widget that adds a scopedWillPopCallback must ensure that the callback
/// is removed with [removeScopedWillPopCallback] by the time the widget has
/// been disposed. A stateful widget can do this in its dispose method
/// (continuing the previous example):
///
///
/// ```dart
/// ```dart
/// @override
/// @override
/// void dispose() {
/// void dispose() {
/// _route?.removeScopedWillPopCallback(askTheUserIfTheyAreSure);
/// _route?.removeScopedWillPopCallback(askTheUserIfTheyAreSure);
/// _route = null;
/// super.dispose();
/// super.dispose();
/// }
/// }
/// ```
/// ```
///
///
/// See also:
/// See also:
///
///
/// * [WillPopScope], which manages the registration and unregistration
/// process automatically.
/// * [Form], which provides an `onWillPop` callback that uses this mechanism.
/// * [Form], which provides an `onWillPop` callback that uses this mechanism.
/// * [willPop], which runs the callbacks added with this method.
/// * [willPop], which runs the callbacks added with this method.
/// * [removeScopedWillPopCallback], which removes a callback from the list
/// * [removeScopedWillPopCallback], which removes a callback from the list
...
...
packages/flutter/lib/src/widgets/will_pop_scope.dart
0 → 100644
View file @
66386255
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/foundation.dart'
;
import
'framework.dart'
;
import
'routes.dart'
;
/// Registers a callback to veto attempts by the user to dismiss the enclosing
/// [ModalRoute].
///
/// See also:
///
/// * [ModalRoute.addScopedWillPopCallback] and [ModalScope.removeScopedWillPopCallback],
/// which this widget uses to register and unregister [onWillPop].
class
WillPopScope
extends
StatefulWidget
{
/// Creates a widget that registers a callback to veto attempts by the user to
/// dismiss the enclosing [ModalRoute].
///
/// The [child] argument must not be null.
WillPopScope
({
Key
key
,
@required
this
.
child
,
@required
this
.
onWillPop
,
})
:
super
(
key:
key
)
{
assert
(
child
!=
null
);
}
/// The widget below this widget in the tree.
final
Widget
child
;
/// Called to veto attempts by the user to dismiss the enclosing [ModalRoute].
///
/// If the callback returns a Future that resolves to false, the enclosing
/// route will not be popped.
WillPopCallback
onWillPop
;
@override
_WillPopScopeState
createState
()
=>
new
_WillPopScopeState
();
}
class
_WillPopScopeState
extends
State
<
WillPopScope
>
{
ModalRoute
<
dynamic
>
_route
;
@override
void
dependenciesChanged
()
{
super
.
dependenciesChanged
();
if
(
config
.
onWillPop
!=
null
)
_route
?.
removeScopedWillPopCallback
(
config
.
onWillPop
);
_route
=
ModalRoute
.
of
(
context
);
if
(
config
.
onWillPop
!=
null
)
_route
?.
addScopedWillPopCallback
(
config
.
onWillPop
);
}
@override
void
didUpdateConfig
(
WillPopScope
oldConfig
)
{
assert
(
_route
==
ModalRoute
.
of
(
context
));
if
(
config
.
onWillPop
!=
oldConfig
.
onWillPop
&&
_route
!=
null
)
{
if
(
oldConfig
.
onWillPop
!=
null
)
_route
.
removeScopedWillPopCallback
(
oldConfig
.
onWillPop
);
if
(
config
.
onWillPop
!=
null
)
_route
.
addScopedWillPopCallback
(
config
.
onWillPop
);
}
}
@override
void
dispose
()
{
if
(
config
.
onWillPop
!=
null
)
_route
?.
removeScopedWillPopCallback
(
config
.
onWillPop
);
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
=>
config
.
child
;
}
packages/flutter/lib/widgets.dart
View file @
66386255
...
@@ -66,5 +66,6 @@ export 'src/widgets/title.dart';
...
@@ -66,5 +66,6 @@ export 'src/widgets/title.dart';
export
'src/widgets/transitions.dart'
;
export
'src/widgets/transitions.dart'
;
export
'src/widgets/unique_widget.dart'
;
export
'src/widgets/unique_widget.dart'
;
export
'src/widgets/viewport.dart'
;
export
'src/widgets/viewport.dart'
;
export
'src/widgets/will_pop_scope.dart'
;
export
'package:vector_math/vector_math_64.dart'
show
Matrix4
;
export
'package:vector_math/vector_math_64.dart'
show
Matrix4
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment