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
d0161464
Commit
d0161464
authored
Jan 16, 2020
by
rami-a
Committed by
Flutter GitHub Bot
Jan 16, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow for cupertino modal popups to be dismissed with semantics (#48915)
parent
eaa0e620
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
3 deletions
+90
-3
cupertino_picker_demo.dart
...ter_gallery/lib/demo/cupertino/cupertino_picker_demo.dart
+5
-0
picker.dart
packages/flutter/lib/src/cupertino/picker.dart
+2
-1
route.dart
packages/flutter/lib/src/cupertino/route.dart
+11
-2
route_test.dart
packages/flutter/test/cupertino/route_test.dart
+72
-0
No files found.
examples/flutter_gallery/lib/demo/cupertino/cupertino_picker_demo.dart
View file @
d0161464
...
...
@@ -108,6 +108,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
onTap:
()
async
{
await
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
{
return
_BottomPicker
(
child:
CupertinoPicker
(
...
...
@@ -144,6 +145,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
onTap:
()
{
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
{
return
_BottomPicker
(
child:
CupertinoTimerPicker
(
...
...
@@ -176,6 +178,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
onTap:
()
{
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
{
return
_BottomPicker
(
child:
CupertinoDatePicker
(
...
...
@@ -207,6 +210,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
onTap:
()
{
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
{
return
_BottomPicker
(
child:
CupertinoDatePicker
(
...
...
@@ -238,6 +242,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
onTap:
()
{
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
{
return
_BottomPicker
(
child:
CupertinoDatePicker
(
...
...
packages/flutter/lib/src/cupertino/picker.dart
View file @
d0161464
...
...
@@ -35,7 +35,8 @@ const double _kOverAndUnderCenterOpacity = 0.447;
/// that child the initially selected child.
///
/// Can be used with [showCupertinoModalPopup] to display the picker modally at the
/// bottom of the screen.
/// bottom of the screen. When calling [showCupertinoModalPopup], be sure to set
/// `semanticsDismissible` to true to enable dismissing the modal via semantics.
///
/// Sizes itself to its parent. All children are sized to the same size based
/// on [itemExtent].
...
...
packages/flutter/lib/src/cupertino/route.dart
View file @
d0161464
...
...
@@ -792,14 +792,18 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
this
.
barrierColor
,
this
.
barrierLabel
,
this
.
builder
,
bool
semanticsDismissible
,
ImageFilter
filter
,
RouteSettings
settings
,
})
:
super
(
filter:
filter
,
settings:
settings
,
);
)
{
_semanticsDismissible
=
semanticsDismissible
;
}
final
WidgetBuilder
builder
;
bool
_semanticsDismissible
;
@override
final
String
barrierLabel
;
...
...
@@ -811,7 +815,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
bool
get
barrierDismissible
=>
true
;
@override
bool
get
semanticsDismissible
=>
false
;
bool
get
semanticsDismissible
=>
_semanticsDismissible
??
false
;
@override
Duration
get
transitionDuration
=>
_kModalPopupTransitionDuration
;
...
...
@@ -871,6 +875,9 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
/// popup to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default.
///
/// The `semanticsDismissble` argument is used to determine whether the
/// semantics of the modal barrier are included in the semantics tree.
///
/// The `builder` argument typically builds a [CupertinoActionSheet] widget.
/// Content below the widget is dimmed with a [ModalBarrier]. The widget built
/// by the `builder` does not share a context with the location that
...
...
@@ -891,6 +898,7 @@ Future<T> showCupertinoModalPopup<T>({
@required
WidgetBuilder
builder
,
ImageFilter
filter
,
bool
useRootNavigator
=
true
,
bool
semanticsDismissible
,
})
{
assert
(
useRootNavigator
!=
null
);
return
Navigator
.
of
(
context
,
rootNavigator:
useRootNavigator
).
push
(
...
...
@@ -899,6 +907,7 @@ Future<T> showCupertinoModalPopup<T>({
barrierLabel:
'Dismiss'
,
builder:
builder
,
filter:
filter
,
semanticsDismissible:
semanticsDismissible
,
),
);
}
...
...
packages/flutter/test/cupertino/route_test.dart
View file @
d0161464
...
...
@@ -3,11 +3,14 @@
// found in the LICENSE file.
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../widgets/semantics_tester.dart'
;
void
main
(
)
{
MockNavigatorObserver
navigatorObserver
;
...
...
@@ -1052,6 +1055,75 @@ void main() {
expect
(
rootObserver
.
dialogCount
,
0
);
expect
(
nestedObserver
.
dialogCount
,
1
);
});
testWidgets
(
'showCupertinoModalPopup does not allow for semantics dismiss by default'
,
(
WidgetTester
tester
)
async
{
debugDefaultTargetPlatformOverride
=
TargetPlatform
.
iOS
;
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
await
tester
.
pumpWidget
(
CupertinoApp
(
home:
Navigator
(
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
GestureDetector
(
onTap:
()
async
{
await
showCupertinoModalPopup
<
void
>(
context:
context
,
builder:
(
BuildContext
context
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'tap'
),
);
},
);
},
),
));
// Push the route.
await
tester
.
tap
(
find
.
text
(
'tap'
));
await
tester
.
pumpAndSettle
();
expect
(
semantics
,
isNot
(
includesNodeWith
(
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
label:
'Dismiss'
,
)));
debugDefaultTargetPlatformOverride
=
null
;
});
testWidgets
(
'showCupertinoModalPopup allows for semantics dismiss when set'
,
(
WidgetTester
tester
)
async
{
debugDefaultTargetPlatformOverride
=
TargetPlatform
.
iOS
;
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
await
tester
.
pumpWidget
(
CupertinoApp
(
home:
Navigator
(
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
GestureDetector
(
onTap:
()
async
{
await
showCupertinoModalPopup
<
void
>(
context:
context
,
semanticsDismissible:
true
,
builder:
(
BuildContext
context
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'tap'
),
);
},
);
},
),
));
// Push the route.
await
tester
.
tap
(
find
.
text
(
'tap'
));
await
tester
.
pumpAndSettle
();
expect
(
semantics
,
includesNodeWith
(
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
label:
'Dismiss'
,
));
debugDefaultTargetPlatformOverride
=
null
;
});
}
class
MockNavigatorObserver
extends
Mock
implements
NavigatorObserver
{}
...
...
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