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
58ad6e1b
Unverified
Commit
58ad6e1b
authored
Feb 16, 2022
by
Taha Tesser
Committed by
GitHub
Feb 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dismiss Modal Barrier on `handleTapCancel` (#98191)
parent
0acfb216
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
43 additions
and
5 deletions
+43
-5
modal_barrier.dart
packages/flutter/lib/src/widgets/modal_barrier.dart
+10
-5
modal_barrier_test.dart
packages/flutter/test/widgets/modal_barrier_test.dart
+33
-0
No files found.
packages/flutter/lib/src/widgets/modal_barrier.dart
View file @
58ad6e1b
...
@@ -47,7 +47,8 @@ class ModalBarrier extends StatelessWidget {
...
@@ -47,7 +47,8 @@ class ModalBarrier extends StatelessWidget {
/// [ModalBarrier] built by [ModalRoute] pages.
/// [ModalBarrier] built by [ModalRoute] pages.
final
Color
?
color
;
final
Color
?
color
;
/// Specifies if the barrier will be dismissed when the user taps on it.
/// Specifies if the barrier will be dismissed when the user taps or
/// performs a scroll gesture on it.
///
///
/// If true, and [onDismiss] is non-null, [onDismiss] will be called,
/// If true, and [onDismiss] is non-null, [onDismiss] will be called,
/// otherwise the current route will be popped from the ambient [Navigator].
/// otherwise the current route will be popped from the ambient [Navigator].
...
@@ -228,12 +229,14 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer {
...
@@ -228,12 +229,14 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer {
:
super
(
debugOwner:
debugOwner
);
:
super
(
debugOwner:
debugOwner
);
VoidCallback
?
onAnyTapUp
;
VoidCallback
?
onAnyTapUp
;
VoidCallback
?
onAnyTapCancel
;
@protected
@protected
@override
@override
bool
isPointerAllowed
(
PointerDownEvent
event
)
{
bool
isPointerAllowed
(
PointerDownEvent
event
)
{
if
(
onAnyTapUp
==
null
)
if
(
onAnyTapUp
==
null
&&
onAnyTapCancel
==
null
)
{
return
false
;
return
false
;
}
return
super
.
isPointerAllowed
(
event
);
return
super
.
isPointerAllowed
(
event
);
}
}
...
@@ -252,7 +255,7 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer {
...
@@ -252,7 +255,7 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer {
@protected
@protected
@override
@override
void
handleTapCancel
({
PointerDownEvent
?
down
,
PointerCancelEvent
?
cancel
,
String
?
reason
})
{
void
handleTapCancel
({
PointerDownEvent
?
down
,
PointerCancelEvent
?
cancel
,
String
?
reason
})
{
// Do nothing.
onAnyTapCancel
?.
call
();
}
}
@override
@override
...
@@ -272,9 +275,10 @@ class _ModalBarrierSemanticsDelegate extends SemanticsGestureDelegate {
...
@@ -272,9 +275,10 @@ class _ModalBarrierSemanticsDelegate extends SemanticsGestureDelegate {
class
_AnyTapGestureRecognizerFactory
extends
GestureRecognizerFactory
<
_AnyTapGestureRecognizer
>
{
class
_AnyTapGestureRecognizerFactory
extends
GestureRecognizerFactory
<
_AnyTapGestureRecognizer
>
{
const
_AnyTapGestureRecognizerFactory
({
this
.
onAnyTapUp
});
const
_AnyTapGestureRecognizerFactory
({
this
.
onAnyTapUp
,
this
.
onAnyTapCancel
});
final
VoidCallback
?
onAnyTapUp
;
final
VoidCallback
?
onAnyTapUp
;
final
VoidCallback
?
onAnyTapCancel
;
@override
@override
_AnyTapGestureRecognizer
constructor
()
=>
_AnyTapGestureRecognizer
();
_AnyTapGestureRecognizer
constructor
()
=>
_AnyTapGestureRecognizer
();
...
@@ -282,6 +286,7 @@ class _AnyTapGestureRecognizerFactory extends GestureRecognizerFactory<_AnyTapGe
...
@@ -282,6 +286,7 @@ class _AnyTapGestureRecognizerFactory extends GestureRecognizerFactory<_AnyTapGe
@override
@override
void
initializer
(
_AnyTapGestureRecognizer
instance
)
{
void
initializer
(
_AnyTapGestureRecognizer
instance
)
{
instance
.
onAnyTapUp
=
onAnyTapUp
;
instance
.
onAnyTapUp
=
onAnyTapUp
;
instance
.
onAnyTapCancel
=
onAnyTapCancel
;
}
}
}
}
...
@@ -307,7 +312,7 @@ class _ModalBarrierGestureDetector extends StatelessWidget {
...
@@ -307,7 +312,7 @@ class _ModalBarrierGestureDetector extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
Map
<
Type
,
GestureRecognizerFactory
>
gestures
=
<
Type
,
GestureRecognizerFactory
>{
final
Map
<
Type
,
GestureRecognizerFactory
>
gestures
=
<
Type
,
GestureRecognizerFactory
>{
_AnyTapGestureRecognizer:
_AnyTapGestureRecognizerFactory
(
onAnyTapUp:
onDismiss
),
_AnyTapGestureRecognizer:
_AnyTapGestureRecognizerFactory
(
onAnyTapUp:
onDismiss
,
onAnyTapCancel:
onDismiss
),
};
};
return
RawGestureDetector
(
return
RawGestureDetector
(
...
...
packages/flutter/test/widgets/modal_barrier_test.dart
View file @
58ad6e1b
...
@@ -251,6 +251,39 @@ void main() {
...
@@ -251,6 +251,39 @@ void main() {
);
);
});
});
testWidgets
(
'ModalBarrier pops the Navigator when dismissed by tap cancel'
,
(
WidgetTester
tester
)
async
{
final
Map
<
String
,
WidgetBuilder
>
routes
=
<
String
,
WidgetBuilder
>{
'/'
:
(
BuildContext
context
)
=>
const
FirstWidget
(),
'/modal'
:
(
BuildContext
context
)
=>
const
SecondWidget
(),
};
await
tester
.
pumpWidget
(
MaterialApp
(
routes:
routes
));
// Initially the barrier is not visible
expect
(
find
.
byKey
(
const
ValueKey
<
String
>(
'barrier'
)),
findsNothing
);
// Tapping on X routes to the barrier
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// begin transition
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// end transition
// Press the barrier; it shouldn't dismiss yet
final
TestGesture
gesture
=
await
tester
.
press
(
find
.
byKey
(
const
ValueKey
<
String
>(
'barrier'
)),
);
await
tester
.
pumpAndSettle
();
// begin transition
expect
(
find
.
byKey
(
const
ValueKey
<
String
>(
'barrier'
)),
findsOneWidget
);
// Cancel the pointer; the barrier should be dismissed
await
gesture
.
cancel
();
await
tester
.
pumpAndSettle
(
const
Duration
(
seconds:
1
));
// end transition
expect
(
find
.
byKey
(
const
ValueKey
<
String
>(
'barrier'
)),
findsNothing
,
reason:
'The route should have been dismissed by tapping the barrier.'
,
);
});
testWidgets
(
'ModalBarrier may pop the Navigator when competing with other gestures'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'ModalBarrier may pop the Navigator when competing with other gestures'
,
(
WidgetTester
tester
)
async
{
final
Map
<
String
,
WidgetBuilder
>
routes
=
<
String
,
WidgetBuilder
>{
final
Map
<
String
,
WidgetBuilder
>
routes
=
<
String
,
WidgetBuilder
>{
'/'
:
(
BuildContext
context
)
=>
const
FirstWidget
(),
'/'
:
(
BuildContext
context
)
=>
const
FirstWidget
(),
...
...
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