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
2e414833
Commit
2e414833
authored
Nov 01, 2019
by
Brian Egan
Committed by
Kate Lovett
Nov 01, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add "navigator" option to "showDialog" and "showGeneralDialog" (#42842)
parent
694b2d89
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
826 additions
and
27 deletions
+826
-27
route.dart
packages/flutter/lib/src/cupertino/route.dart
+17
-4
about.dart
packages/flutter/lib/src/material/about.dart
+15
-4
date_picker.dart
packages/flutter/lib/src/material/date_picker.dart
+5
-2
dialog.dart
packages/flutter/lib/src/material/dialog.dart
+12
-5
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+7
-1
time_picker.dart
packages/flutter/lib/src/material/time_picker.dart
+5
-2
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+15
-9
route_test.dart
packages/flutter/test/cupertino/route_test.dart
+158
-0
about_test.dart
packages/flutter/test/material/about_test.dart
+168
-0
date_picker_test.dart
packages/flutter/test/material/date_picker_test.dart
+86
-0
dialog_test.dart
packages/flutter/test/material/dialog_test.dart
+83
-0
popup_menu_test.dart
packages/flutter/test/material/popup_menu_test.dart
+89
-0
time_picker_test.dart
packages/flutter/test/material/time_picker_test.dart
+79
-0
routes_test.dart
packages/flutter/test/widgets/routes_test.dart
+87
-0
No files found.
packages/flutter/lib/src/cupertino/route.dart
View file @
2e414833
...
@@ -864,6 +864,10 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
...
@@ -864,6 +864,10 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
/// It is only used when the method is called. Its corresponding widget can be
/// It is only used when the method is called. Its corresponding widget can be
/// safely removed from the tree before the popup is closed.
/// safely removed from the tree before the popup is closed.
///
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// popup to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default.
///
/// The `builder` argument typically builds a [CupertinoActionSheet] widget.
/// The `builder` argument typically builds a [CupertinoActionSheet] widget.
/// Content below the widget is dimmed with a [ModalBarrier]. The widget built
/// Content below the widget is dimmed with a [ModalBarrier]. The widget built
/// by the `builder` does not share a context with the location that
/// by the `builder` does not share a context with the location that
...
@@ -882,8 +886,10 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
...
@@ -882,8 +886,10 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
Future
<
T
>
showCupertinoModalPopup
<
T
>({
Future
<
T
>
showCupertinoModalPopup
<
T
>({
@required
BuildContext
context
,
@required
BuildContext
context
,
@required
WidgetBuilder
builder
,
@required
WidgetBuilder
builder
,
bool
useRootNavigator
=
true
,
})
{
})
{
return
Navigator
.
of
(
context
,
rootNavigator:
true
).
push
(
assert
(
useRootNavigator
!=
null
);
return
Navigator
.
of
(
context
,
rootNavigator:
useRootNavigator
).
push
(
_CupertinoModalPopupRoute
<
T
>(
_CupertinoModalPopupRoute
<
T
>(
builder:
builder
,
builder:
builder
,
barrierLabel:
'Dismiss'
,
barrierLabel:
'Dismiss'
,
...
@@ -933,14 +939,18 @@ Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<double>
...
@@ -933,14 +939,18 @@ Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<double>
/// It is only used when the method is called. Its corresponding widget can
/// It is only used when the method is called. Its corresponding widget can
/// be safely removed from the tree before the dialog is closed.
/// be safely removed from the tree before the dialog is closed.
///
///
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// The `useRootNavigator` argument is used to determine whether to push the
/// [Navigator.pop] when the dialog was closed.
/// dialog to the [Navigator] furthest from or nearest to the given `context`.
/// By default, `useRootNavigator` is `true` and the dialog route created by
/// this method is pushed to the root navigator.
///
///
/// The dialog route created by this method is pushed to the root navigator.
/// If the application has multiple [Navigator] objects, it may be necessary to
/// If the application has multiple [Navigator] objects, it may be necessary to
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// dialog rather than just `Navigator.pop(context, result)`.
/// dialog rather than just `Navigator.pop(context, result)`.
///
///
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed.
///
/// See also:
/// See also:
///
///
/// * [CupertinoDialog], an iOS-style dialog.
/// * [CupertinoDialog], an iOS-style dialog.
...
@@ -951,8 +961,10 @@ Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<double>
...
@@ -951,8 +961,10 @@ Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<double>
Future
<
T
>
showCupertinoDialog
<
T
>({
Future
<
T
>
showCupertinoDialog
<
T
>({
@required
BuildContext
context
,
@required
BuildContext
context
,
@required
WidgetBuilder
builder
,
@required
WidgetBuilder
builder
,
bool
useRootNavigator
=
true
,
})
{
})
{
assert
(
builder
!=
null
);
assert
(
builder
!=
null
);
assert
(
useRootNavigator
!=
null
);
return
showGeneralDialog
(
return
showGeneralDialog
(
context:
context
,
context:
context
,
barrierDismissible:
false
,
barrierDismissible:
false
,
...
@@ -963,5 +975,6 @@ Future<T> showCupertinoDialog<T>({
...
@@ -963,5 +975,6 @@ Future<T> showCupertinoDialog<T>({
return
builder
(
context
);
return
builder
(
context
);
},
},
transitionBuilder:
_buildCupertinoDialogTransitions
,
transitionBuilder:
_buildCupertinoDialogTransitions
,
useRootNavigator:
useRootNavigator
,
);
);
}
}
packages/flutter/lib/src/material/about.dart
View file @
2e414833
...
@@ -223,8 +223,8 @@ class AboutListTile extends StatelessWidget {
...
@@ -223,8 +223,8 @@ class AboutListTile extends StatelessWidget {
/// The licenses shown on the [LicensePage] are those returned by the
/// The licenses shown on the [LicensePage] are those returned by the
/// [LicenseRegistry] API, which can be used to add more licenses to the list.
/// [LicenseRegistry] API, which can be used to add more licenses to the list.
///
///
/// The
`context` argument is passed to [showDialog], the documentation for
/// The
[context] and [useRootNavigator] arguments are passed to [showDialog],
/// which discusses how it is used.
///
the documentation for
which discusses how it is used.
void
showAboutDialog
(
{
void
showAboutDialog
(
{
@required
BuildContext
context
,
@required
BuildContext
context
,
String
applicationName
,
String
applicationName
,
...
@@ -232,10 +232,13 @@ void showAboutDialog({
...
@@ -232,10 +232,13 @@ void showAboutDialog({
Widget
applicationIcon
,
Widget
applicationIcon
,
String
applicationLegalese
,
String
applicationLegalese
,
List
<
Widget
>
children
,
List
<
Widget
>
children
,
bool
useRootNavigator
=
true
,
})
{
})
{
assert
(
context
!=
null
);
assert
(
context
!=
null
);
assert
(
useRootNavigator
!=
null
);
showDialog
<
void
>(
showDialog
<
void
>(
context:
context
,
context:
context
,
useRootNavigator:
useRootNavigator
,
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
AboutDialog
(
return
AboutDialog
(
applicationName:
applicationName
,
applicationName:
applicationName
,
...
@@ -251,7 +254,13 @@ void showAboutDialog({
...
@@ -251,7 +254,13 @@ void showAboutDialog({
/// Displays a [LicensePage], which shows licenses for software used by the
/// Displays a [LicensePage], which shows licenses for software used by the
/// application.
/// application.
///
///
/// The arguments correspond to the properties on [LicensePage].
/// The application arguments correspond to the properties on [LicensePage].
///
/// The `context` argument is used to look up the [Navigator] for the page.
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// page to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default.
///
///
/// If the application has a [Drawer], consider using [AboutListTile] instead
/// If the application has a [Drawer], consider using [AboutListTile] instead
/// of calling this directly.
/// of calling this directly.
...
@@ -267,9 +276,11 @@ void showLicensePage({
...
@@ -267,9 +276,11 @@ void showLicensePage({
String
applicationVersion
,
String
applicationVersion
,
Widget
applicationIcon
,
Widget
applicationIcon
,
String
applicationLegalese
,
String
applicationLegalese
,
bool
useRootNavigator
=
false
,
})
{
})
{
assert
(
context
!=
null
);
assert
(
context
!=
null
);
Navigator
.
push
(
context
,
MaterialPageRoute
<
void
>(
assert
(
useRootNavigator
!=
null
);
Navigator
.
of
(
context
,
rootNavigator:
useRootNavigator
).
push
(
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
=>
LicensePage
(
builder:
(
BuildContext
context
)
=>
LicensePage
(
applicationName:
applicationName
,
applicationName:
applicationName
,
applicationVersion:
applicationVersion
,
applicationVersion:
applicationVersion
,
...
...
packages/flutter/lib/src/material/date_picker.dart
View file @
2e414833
...
@@ -1085,8 +1085,8 @@ typedef SelectableDayPredicate = bool Function(DateTime day);
...
@@ -1085,8 +1085,8 @@ typedef SelectableDayPredicate = bool Function(DateTime day);
/// provided by [Directionality]. If both [locale] and [textDirection] are not
/// provided by [Directionality]. If both [locale] and [textDirection] are not
/// null, [textDirection] overrides the direction chosen for the [locale].
/// null, [textDirection] overrides the direction chosen for the [locale].
///
///
/// The [context] a
rgument is passed to [showDialog], the documentation for
/// The [context] a
nd [useRootNavigator] arguments are passed to [showDialog],
/// which discusses how it is used.
///
the documentation for
which discusses how it is used.
///
///
/// The [builder] parameter can be used to wrap the dialog widget
/// The [builder] parameter can be used to wrap the dialog widget
/// to add inherited widgets like [Theme].
/// to add inherited widgets like [Theme].
...
@@ -1133,10 +1133,12 @@ Future<DateTime> showDatePicker({
...
@@ -1133,10 +1133,12 @@ Future<DateTime> showDatePicker({
Locale
locale
,
Locale
locale
,
TextDirection
textDirection
,
TextDirection
textDirection
,
TransitionBuilder
builder
,
TransitionBuilder
builder
,
bool
useRootNavigator
=
true
,
})
async
{
})
async
{
assert
(
initialDate
!=
null
);
assert
(
initialDate
!=
null
);
assert
(
firstDate
!=
null
);
assert
(
firstDate
!=
null
);
assert
(
lastDate
!=
null
);
assert
(
lastDate
!=
null
);
assert
(
useRootNavigator
!=
null
);
assert
(!
initialDate
.
isBefore
(
firstDate
),
'initialDate must be on or after firstDate'
);
assert
(!
initialDate
.
isBefore
(
firstDate
),
'initialDate must be on or after firstDate'
);
assert
(!
initialDate
.
isAfter
(
lastDate
),
'initialDate must be on or before lastDate'
);
assert
(!
initialDate
.
isAfter
(
lastDate
),
'initialDate must be on or before lastDate'
);
assert
(!
firstDate
.
isAfter
(
lastDate
),
'lastDate must be on or after firstDate'
);
assert
(!
firstDate
.
isAfter
(
lastDate
),
'lastDate must be on or after firstDate'
);
...
@@ -1173,6 +1175,7 @@ Future<DateTime> showDatePicker({
...
@@ -1173,6 +1175,7 @@ Future<DateTime> showDatePicker({
return
await
showDialog
<
DateTime
>(
return
await
showDialog
<
DateTime
>(
context:
context
,
context:
context
,
useRootNavigator:
useRootNavigator
,
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
builder
==
null
?
child
:
builder
(
context
,
child
);
return
builder
==
null
?
child
:
builder
(
context
,
child
);
},
},
...
...
packages/flutter/lib/src/material/dialog.dart
View file @
2e414833
...
@@ -655,20 +655,24 @@ Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> a
...
@@ -655,20 +655,24 @@ Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> a
/// `showDialog` is originally called from. Use a [StatefulBuilder] or a
/// `showDialog` is originally called from. Use a [StatefulBuilder] or a
/// custom [StatefulWidget] if the dialog needs to update dynamically.
/// custom [StatefulWidget] if the dialog needs to update dynamically.
///
///
/// The `child` argument is deprecated, and should be replaced with `builder`.
///
/// The `context` argument is used to look up the [Navigator] and [Theme] for
/// The `context` argument is used to look up the [Navigator] and [Theme] for
/// the dialog. It is only used when the method is called. Its corresponding
/// the dialog. It is only used when the method is called. Its corresponding
/// widget can be safely removed from the tree before the dialog is closed.
/// widget can be safely removed from the tree before the dialog is closed.
///
///
/// The `child` argument is deprecated, and should be replaced with `builder`.
/// The `useRootNavigator` argument is used to determine whether to push the
/// dialog to the [Navigator] furthest from or nearest to the given `context`.
/// By default, `useRootNavigator` is `true` and the dialog route created by
/// this method is pushed to the root navigator.
///
///
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed.
///
/// The dialog route created by this method is pushed to the root navigator.
/// If the application has multiple [Navigator] objects, it may be necessary to
/// If the application has multiple [Navigator] objects, it may be necessary to
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// dialog rather than just `Navigator.pop(context, result)`.
/// dialog rather than just `Navigator.pop(context, result)`.
///
///
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed.
///
/// See also:
/// See also:
///
///
/// * [AlertDialog], for dialogs that have a row of buttons below a body.
/// * [AlertDialog], for dialogs that have a row of buttons below a body.
...
@@ -687,8 +691,10 @@ Future<T> showDialog<T>({
...
@@ -687,8 +691,10 @@ Future<T> showDialog<T>({
'is appropriate for widgets built in the dialog.'
'is appropriate for widgets built in the dialog.'
)
Widget
child
,
)
Widget
child
,
WidgetBuilder
builder
,
WidgetBuilder
builder
,
bool
useRootNavigator
=
true
,
})
{
})
{
assert
(
child
==
null
||
builder
==
null
);
assert
(
child
==
null
||
builder
==
null
);
assert
(
useRootNavigator
!=
null
);
assert
(
debugCheckHasMaterialLocalizations
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
final
ThemeData
theme
=
Theme
.
of
(
context
,
shadowThemeOnly:
true
);
final
ThemeData
theme
=
Theme
.
of
(
context
,
shadowThemeOnly:
true
);
...
@@ -711,5 +717,6 @@ Future<T> showDialog<T>({
...
@@ -711,5 +717,6 @@ Future<T> showDialog<T>({
barrierColor:
Colors
.
black54
,
barrierColor:
Colors
.
black54
,
transitionDuration:
const
Duration
(
milliseconds:
150
),
transitionDuration:
const
Duration
(
milliseconds:
150
),
transitionBuilder:
_buildMaterialDialogTransitions
,
transitionBuilder:
_buildMaterialDialogTransitions
,
useRootNavigator:
useRootNavigator
,
);
);
}
}
packages/flutter/lib/src/material/popup_menu.dart
View file @
2e414833
...
@@ -790,6 +790,10 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
...
@@ -790,6 +790,10 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
/// the menu. It is only used when the method is called. Its corresponding
/// the menu. It is only used when the method is called. Its corresponding
/// widget can be safely removed from the tree before the popup menu is closed.
/// widget can be safely removed from the tree before the popup menu is closed.
///
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// menu to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default.
///
/// The `semanticLabel` argument is used by accessibility frameworks to
/// The `semanticLabel` argument is used by accessibility frameworks to
/// announce screen transitions when the menu is opened and closed. If this
/// announce screen transitions when the menu is opened and closed. If this
/// label is not provided, it will default to
/// label is not provided, it will default to
...
@@ -814,9 +818,11 @@ Future<T> showMenu<T>({
...
@@ -814,9 +818,11 @@ Future<T> showMenu<T>({
ShapeBorder
shape
,
ShapeBorder
shape
,
Color
color
,
Color
color
,
bool
captureInheritedThemes
=
true
,
bool
captureInheritedThemes
=
true
,
bool
useRootNavigator
=
false
,
})
{
})
{
assert
(
context
!=
null
);
assert
(
context
!=
null
);
assert
(
position
!=
null
);
assert
(
position
!=
null
);
assert
(
useRootNavigator
!=
null
);
assert
(
items
!=
null
&&
items
.
isNotEmpty
);
assert
(
items
!=
null
&&
items
.
isNotEmpty
);
assert
(
captureInheritedThemes
!=
null
);
assert
(
captureInheritedThemes
!=
null
);
assert
(
debugCheckHasMaterialLocalizations
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
...
@@ -831,7 +837,7 @@ Future<T> showMenu<T>({
...
@@ -831,7 +837,7 @@ Future<T> showMenu<T>({
label
=
semanticLabel
??
MaterialLocalizations
.
of
(
context
)?.
popupMenuLabel
;
label
=
semanticLabel
??
MaterialLocalizations
.
of
(
context
)?.
popupMenuLabel
;
}
}
return
Navigator
.
push
(
context
,
_PopupMenuRoute
<
T
>(
return
Navigator
.
of
(
context
,
rootNavigator:
useRootNavigator
).
push
(
_PopupMenuRoute
<
T
>(
position:
position
,
position:
position
,
items:
items
,
items:
items
,
initialValue:
initialValue
,
initialValue:
initialValue
,
...
...
packages/flutter/lib/src/material/time_picker.dart
View file @
2e414833
...
@@ -1731,8 +1731,8 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
...
@@ -1731,8 +1731,8 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
/// ```
/// ```
/// {@end-tool}
/// {@end-tool}
///
///
/// The [context] a
rgument is passed to [showDialog], the documentation for
/// The [context] a
nd [useRootNavigator] arguments are passed to [showDialog],
/// which discusses how it is used.
///
the documentation for
which discusses how it is used.
///
///
/// The [builder] parameter can be used to wrap the dialog widget
/// The [builder] parameter can be used to wrap the dialog widget
/// to add inherited widgets like [Localizations.override],
/// to add inherited widgets like [Localizations.override],
...
@@ -1780,14 +1780,17 @@ Future<TimeOfDay> showTimePicker({
...
@@ -1780,14 +1780,17 @@ Future<TimeOfDay> showTimePicker({
@required
BuildContext
context
,
@required
BuildContext
context
,
@required
TimeOfDay
initialTime
,
@required
TimeOfDay
initialTime
,
TransitionBuilder
builder
,
TransitionBuilder
builder
,
bool
useRootNavigator
=
true
,
})
async
{
})
async
{
assert
(
context
!=
null
);
assert
(
context
!=
null
);
assert
(
initialTime
!=
null
);
assert
(
initialTime
!=
null
);
assert
(
useRootNavigator
!=
null
);
assert
(
debugCheckHasMaterialLocalizations
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
final
Widget
dialog
=
_TimePickerDialog
(
initialTime:
initialTime
);
final
Widget
dialog
=
_TimePickerDialog
(
initialTime:
initialTime
);
return
await
showDialog
<
TimeOfDay
>(
return
await
showDialog
<
TimeOfDay
>(
context:
context
,
context:
context
,
useRootNavigator:
useRootNavigator
,
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
builder
==
null
?
dialog
:
builder
(
context
,
dialog
);
return
builder
==
null
?
dialog
:
builder
(
context
,
dialog
);
},
},
...
...
packages/flutter/lib/src/widgets/routes.dart
View file @
2e414833
...
@@ -1560,9 +1560,18 @@ class _DialogRoute<T> extends PopupRoute<T> {
...
@@ -1560,9 +1560,18 @@ class _DialogRoute<T> extends PopupRoute<T> {
/// [StatefulWidget] if the dialog needs to update dynamically. The
/// [StatefulWidget] if the dialog needs to update dynamically. The
/// `pageBuilder` argument can not be null.
/// `pageBuilder` argument can not be null.
///
///
/// The `context` argument is used to look up the [Navigator] for the dialog.
/// The `context` argument is used to look up the [Navigator] for the
/// It is only used when the method is called. Its corresponding widget can
/// dialog. It is only used when the method is called. Its corresponding widget
/// be safely removed from the tree before the dialog is closed.
/// can be safely removed from the tree before the dialog is closed.
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// dialog to the [Navigator] furthest from or nearest to the given `context`.
/// By default, `useRootNavigator` is `true` and the dialog route created by
/// this method is pushed to the root navigator.
///
/// If the application has multiple [Navigator] objects, it may be necessary to
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// dialog rather than just `Navigator.pop(context, result)`.
///
///
/// The `barrierDismissible` argument is used to determine whether this route
/// The `barrierDismissible` argument is used to determine whether this route
/// can be dismissed by tapping the modal barrier. This argument defaults
/// can be dismissed by tapping the modal barrier. This argument defaults
...
@@ -1586,11 +1595,6 @@ class _DialogRoute<T> extends PopupRoute<T> {
...
@@ -1586,11 +1595,6 @@ class _DialogRoute<T> extends PopupRoute<T> {
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed.
/// [Navigator.pop] when the dialog was closed.
///
///
/// The dialog route created by this method is pushed to the root navigator.
/// If the application has multiple [Navigator] objects, it may be necessary to
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// dialog rather than just `Navigator.pop(context, result)`.
///
/// See also:
/// See also:
///
///
/// * [showDialog], which displays a Material-style dialog.
/// * [showDialog], which displays a Material-style dialog.
...
@@ -1603,10 +1607,12 @@ Future<T> showGeneralDialog<T>({
...
@@ -1603,10 +1607,12 @@ Future<T> showGeneralDialog<T>({
Color
barrierColor
,
Color
barrierColor
,
Duration
transitionDuration
,
Duration
transitionDuration
,
RouteTransitionsBuilder
transitionBuilder
,
RouteTransitionsBuilder
transitionBuilder
,
bool
useRootNavigator
=
true
,
})
{
})
{
assert
(
pageBuilder
!=
null
);
assert
(
pageBuilder
!=
null
);
assert
(
useRootNavigator
!=
null
);
assert
(!
barrierDismissible
||
barrierLabel
!=
null
);
assert
(!
barrierDismissible
||
barrierLabel
!=
null
);
return
Navigator
.
of
(
context
,
rootNavigator:
true
).
push
<
T
>(
_DialogRoute
<
T
>(
return
Navigator
.
of
(
context
,
rootNavigator:
useRootNavigator
).
push
<
T
>(
_DialogRoute
<
T
>(
pageBuilder:
pageBuilder
,
pageBuilder:
pageBuilder
,
barrierDismissible:
barrierDismissible
,
barrierDismissible:
barrierDismissible
,
barrierLabel:
barrierLabel
,
barrierLabel:
barrierLabel
,
...
...
packages/flutter/test/cupertino/route_test.dart
View file @
2e414833
...
@@ -918,6 +918,164 @@ void main() {
...
@@ -918,6 +918,164 @@ void main() {
expect
(
homeTapCount
,
1
);
expect
(
homeTapCount
,
1
);
expect
(
pageTapCount
,
1
);
expect
(
pageTapCount
,
1
);
});
});
testWidgets
(
'showCupertinoModalPopup uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
PopupObserver
rootObserver
=
PopupObserver
();
final
PopupObserver
nestedObserver
=
PopupObserver
();
await
tester
.
pumpWidget
(
CupertinoApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
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'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
text
(
'tap'
));
expect
(
rootObserver
.
popupCount
,
1
);
expect
(
nestedObserver
.
popupCount
,
0
);
});
testWidgets
(
'showCupertinoModalPopup uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
PopupObserver
rootObserver
=
PopupObserver
();
final
PopupObserver
nestedObserver
=
PopupObserver
();
await
tester
.
pumpWidget
(
CupertinoApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
GestureDetector
(
onTap:
()
async
{
await
showCupertinoModalPopup
<
void
>(
context:
context
,
useRootNavigator:
false
,
builder:
(
BuildContext
context
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'tap'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
text
(
'tap'
));
expect
(
rootObserver
.
popupCount
,
0
);
expect
(
nestedObserver
.
popupCount
,
1
);
});
testWidgets
(
'showCupertinoDialog uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
CupertinoApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
GestureDetector
(
onTap:
()
async
{
await
showCupertinoDialog
<
void
>(
context:
context
,
builder:
(
BuildContext
context
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'tap'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
text
(
'tap'
));
expect
(
rootObserver
.
dialogCount
,
1
);
expect
(
nestedObserver
.
dialogCount
,
0
);
});
testWidgets
(
'showCupertinoDialog uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
CupertinoApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
GestureDetector
(
onTap:
()
async
{
await
showCupertinoDialog
<
void
>(
context:
context
,
useRootNavigator:
false
,
builder:
(
BuildContext
context
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'tap'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
text
(
'tap'
));
expect
(
rootObserver
.
dialogCount
,
0
);
expect
(
nestedObserver
.
dialogCount
,
1
);
});
}
}
class
MockNavigatorObserver
extends
Mock
implements
NavigatorObserver
{}
class
MockNavigatorObserver
extends
Mock
implements
NavigatorObserver
{}
class
PopupObserver
extends
NavigatorObserver
{
int
popupCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_CupertinoModalPopupRoute'
))
{
popupCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
class
DialogObserver
extends
NavigatorObserver
{
int
dialogCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
dialogCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
packages/flutter/test/material/about_test.dart
View file @
2e414833
...
@@ -305,6 +305,150 @@ void main() {
...
@@ -305,6 +305,150 @@ void main() {
tileRect
=
tester
.
getRect
(
find
.
byType
(
AboutListTile
));
tileRect
=
tester
.
getRect
(
find
.
byType
(
AboutListTile
));
expect
(
tileRect
.
height
,
48.0
);
expect
(
tileRect
.
height
,
48.0
);
});
});
testWidgets
(
'showLicensePage uses nested navigator by default'
,
(
WidgetTester
tester
)
async
{
final
LicensePageObserver
rootObserver
=
LicensePageObserver
();
final
LicensePageObserver
nestedObserver
=
LicensePageObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
initialRoute:
'/'
,
onGenerateRoute:
(
_
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
_
,
__
,
___
)
=>
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
_
,
__
)
{
return
RaisedButton
(
onPressed:
()
{
showLicensePage
(
context:
context
,
applicationName:
'A'
,
);
},
child:
const
Text
(
'Show License Page'
),
);
},
);
},
),
);
},
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
licensePageCount
,
0
);
expect
(
nestedObserver
.
licensePageCount
,
1
);
});
testWidgets
(
'showLicensePage uses root navigator if useRootNavigator is true'
,
(
WidgetTester
tester
)
async
{
final
LicensePageObserver
rootObserver
=
LicensePageObserver
();
final
LicensePageObserver
nestedObserver
=
LicensePageObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
initialRoute:
'/'
,
onGenerateRoute:
(
_
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
_
,
__
,
___
)
=>
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
PageRouteBuilder
<
dynamic
>(
pageBuilder:
(
BuildContext
context
,
_
,
__
)
{
return
RaisedButton
(
onPressed:
()
{
showLicensePage
(
context:
context
,
useRootNavigator:
true
,
applicationName:
'A'
,
);
},
child:
const
Text
(
'Show License Page'
),
);
},
);
},
),
);
},
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
licensePageCount
,
1
);
expect
(
nestedObserver
.
licensePageCount
,
0
);
});
testWidgets
(
'showAboutDialog uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
AboutDialogObserver
rootObserver
=
AboutDialogObserver
();
final
AboutDialogObserver
nestedObserver
=
AboutDialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showAboutDialog
(
context:
context
,
applicationName:
'A'
,
);
},
child:
const
Text
(
'Show About Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
1
);
expect
(
nestedObserver
.
dialogCount
,
0
);
});
testWidgets
(
'showAboutDialog uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
AboutDialogObserver
rootObserver
=
AboutDialogObserver
();
final
AboutDialogObserver
nestedObserver
=
AboutDialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showAboutDialog
(
context:
context
,
useRootNavigator:
false
,
applicationName:
'A'
,
);
},
child:
const
Text
(
'Show About Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
0
);
expect
(
nestedObserver
.
dialogCount
,
1
);
});
}
}
class
FakeLicenseEntry
extends
LicenseEntry
{
class
FakeLicenseEntry
extends
LicenseEntry
{
...
@@ -322,3 +466,27 @@ class FakeLicenseEntry extends LicenseEntry {
...
@@ -322,3 +466,27 @@ class FakeLicenseEntry extends LicenseEntry {
return
<
LicenseParagraph
>[];
return
<
LicenseParagraph
>[];
}
}
}
}
class
LicensePageObserver
extends
NavigatorObserver
{
int
licensePageCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
is
MaterialPageRoute
<
dynamic
>)
{
licensePageCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
class
AboutDialogObserver
extends
NavigatorObserver
{
int
dialogCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
dialogCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
packages/flutter/test/material/date_picker_test.dart
View file @
2e414833
...
@@ -897,4 +897,90 @@ void _tests() {
...
@@ -897,4 +897,90 @@ void _tests() {
});
});
});
});
testWidgets
(
'uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
DatePickerObserver
rootObserver
=
DatePickerObserver
();
final
DatePickerObserver
nestedObserver
=
DatePickerObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showDatePicker
(
context:
context
,
initialDate:
DateTime
.
now
(),
firstDate:
DateTime
(
2018
),
lastDate:
DateTime
(
2030
),
builder:
(
BuildContext
context
,
Widget
child
)
{
return
const
SizedBox
();
},
);
},
child:
const
Text
(
'Show Date Picker'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
datePickerCount
,
1
);
expect
(
nestedObserver
.
datePickerCount
,
0
);
});
testWidgets
(
'uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
DatePickerObserver
rootObserver
=
DatePickerObserver
();
final
DatePickerObserver
nestedObserver
=
DatePickerObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showDatePicker
(
context:
context
,
useRootNavigator:
false
,
initialDate:
DateTime
.
now
(),
firstDate:
DateTime
(
2018
),
lastDate:
DateTime
(
2030
),
builder:
(
BuildContext
context
,
Widget
child
)
=>
const
SizedBox
(),
);
},
child:
const
Text
(
'Show Date Picker'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
datePickerCount
,
0
);
expect
(
nestedObserver
.
datePickerCount
,
1
);
});
}
class
DatePickerObserver
extends
NavigatorObserver
{
int
datePickerCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
datePickerCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
}
packages/flutter/test/material/dialog_test.dart
View file @
2e414833
...
@@ -646,6 +646,77 @@ void main() {
...
@@ -646,6 +646,77 @@ void main() {
await
tester
.
pump
();
await
tester
.
pump
();
});
});
testWidgets
(
'showDialog uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showDialog
<
void
>(
context:
context
,
builder:
(
BuildContext
innerContext
)
{
return
const
AlertDialog
(
title:
Text
(
'Title'
));
},
);
},
child:
const
Text
(
'Show Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
1
);
expect
(
nestedObserver
.
dialogCount
,
0
);
});
testWidgets
(
'showDialog uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showDialog
<
void
>(
context:
context
,
useRootNavigator:
false
,
builder:
(
BuildContext
innerContext
)
{
return
const
AlertDialog
(
title:
Text
(
'Title'
));
},
);
},
child:
const
Text
(
'Show Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
0
);
expect
(
nestedObserver
.
dialogCount
,
1
);
});
group
(
'Scrollable title and content'
,
()
{
group
(
'Scrollable title and content'
,
()
{
testWidgets
(
'Title is scrollable'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Title is scrollable'
,
(
WidgetTester
tester
)
async
{
final
Key
titleKey
=
UniqueKey
();
final
Key
titleKey
=
UniqueKey
();
...
@@ -723,3 +794,15 @@ void main() {
...
@@ -723,3 +794,15 @@ void main() {
});
});
});
});
}
}
class
DialogObserver
extends
NavigatorObserver
{
int
dialogCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
dialogCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
packages/flutter/test/material/popup_menu_test.dart
View file @
2e414833
...
@@ -1114,6 +1114,83 @@ void main() {
...
@@ -1114,6 +1114,83 @@ void main() {
expect
(
find
.
text
(
'PopupMenuButton icon'
),
findsOneWidget
);
expect
(
find
.
text
(
'PopupMenuButton icon'
),
findsOneWidget
);
});
});
testWidgets
(
'showMenu uses nested navigator by default'
,
(
WidgetTester
tester
)
async
{
final
MenuObserver
rootObserver
=
MenuObserver
();
final
MenuObserver
nestedObserver
=
MenuObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showMenu
<
int
>(
context:
context
,
position:
const
RelativeRect
.
fromLTRB
(
0
,
0
,
0
,
0
),
items:
<
PopupMenuItem
<
int
>>[
const
PopupMenuItem
<
int
>(
value:
1
,
child:
Text
(
'1'
),
),
],
);
},
child:
const
Text
(
'Show Menu'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
menuCount
,
0
);
expect
(
nestedObserver
.
menuCount
,
1
);
});
testWidgets
(
'showMenu uses root navigator if useRootNavigator is true'
,
(
WidgetTester
tester
)
async
{
final
MenuObserver
rootObserver
=
MenuObserver
();
final
MenuObserver
nestedObserver
=
MenuObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showMenu
<
int
>(
context:
context
,
useRootNavigator:
true
,
position:
const
RelativeRect
.
fromLTRB
(
0
,
0
,
0
,
0
),
items:
<
PopupMenuItem
<
int
>>[
const
PopupMenuItem
<
int
>(
value:
1
,
child:
Text
(
'1'
),
),
],
);
},
child:
const
Text
(
'Show Menu'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
menuCount
,
1
);
expect
(
nestedObserver
.
menuCount
,
0
);
});
}
}
class
TestApp
extends
StatefulWidget
{
class
TestApp
extends
StatefulWidget
{
...
@@ -1153,3 +1230,15 @@ class _TestAppState extends State<TestApp> {
...
@@ -1153,3 +1230,15 @@ class _TestAppState extends State<TestApp> {
);
);
}
}
}
}
class
MenuObserver
extends
NavigatorObserver
{
int
menuCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_PopupMenuRoute'
))
{
menuCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
packages/flutter/test/material/time_picker_test.dart
View file @
2e414833
...
@@ -622,6 +622,73 @@ void _tests() {
...
@@ -622,6 +622,73 @@ void _tests() {
// button and the right edge of the 800 wide window.
// button and the right edge of the 800 wide window.
expect
(
tester
.
getBottomLeft
(
find
.
text
(
'OK'
)).
dx
,
800
-
ltrOkRight
);
expect
(
tester
.
getBottomLeft
(
find
.
text
(
'OK'
)).
dx
,
800
-
ltrOkRight
);
});
});
testWidgets
(
'uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
PickerObserver
rootObserver
=
PickerObserver
();
final
PickerObserver
nestedObserver
=
PickerObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showTimePicker
(
context:
context
,
initialTime:
const
TimeOfDay
(
hour:
7
,
minute:
0
),
);
},
child:
const
Text
(
'Show Picker'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
pickerCount
,
1
);
expect
(
nestedObserver
.
pickerCount
,
0
);
});
testWidgets
(
'uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
PickerObserver
rootObserver
=
PickerObserver
();
final
PickerObserver
nestedObserver
=
PickerObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showTimePicker
(
context:
context
,
useRootNavigator:
false
,
initialTime:
const
TimeOfDay
(
hour:
7
,
minute:
0
),
);
},
child:
const
Text
(
'Show Picker'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
pickerCount
,
0
);
expect
(
nestedObserver
.
pickerCount
,
1
);
});
}
}
final
Finder
findDialPaint
=
find
.
descendant
(
final
Finder
findDialPaint
=
find
.
descendant
(
...
@@ -695,3 +762,15 @@ class _CustomPainterSemanticsTester {
...
@@ -695,3 +762,15 @@ class _CustomPainterSemanticsTester {
expect
(
tester
.
renderObject
(
findDialPaint
),
expectedLabels
);
expect
(
tester
.
renderObject
(
findDialPaint
),
expectedLabels
);
}
}
}
}
class
PickerObserver
extends
NavigatorObserver
{
int
pickerCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
pickerCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
packages/flutter/test/widgets/routes_test.dart
View file @
2e414833
...
@@ -788,6 +788,81 @@ void main() {
...
@@ -788,6 +788,81 @@ void main() {
expect
(
secondaryAnimationPageOne
.
parent
,
kAlwaysDismissedAnimation
);
expect
(
secondaryAnimationPageOne
.
parent
,
kAlwaysDismissedAnimation
);
expect
(
trainHopper2
.
currentTrain
,
isNull
);
// Has been disposed.
expect
(
trainHopper2
.
currentTrain
,
isNull
);
// Has been disposed.
});
});
testWidgets
(
'showGeneralDialog uses root navigator by default'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showGeneralDialog
<
void
>(
context:
context
,
barrierDismissible:
false
,
transitionDuration:
Duration
.
zero
,
pageBuilder:
(
BuildContext
innerContext
,
_
,
__
)
{
return
const
SizedBox
();
},
);
},
child:
const
Text
(
'Show Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
1
);
expect
(
nestedObserver
.
dialogCount
,
0
);
});
testWidgets
(
'showGeneralDialog uses nested navigator if useRootNavigator is false'
,
(
WidgetTester
tester
)
async
{
final
DialogObserver
rootObserver
=
DialogObserver
();
final
DialogObserver
nestedObserver
=
DialogObserver
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorObservers:
<
NavigatorObserver
>[
rootObserver
],
home:
Navigator
(
observers:
<
NavigatorObserver
>[
nestedObserver
],
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
dynamic
>(
builder:
(
BuildContext
context
)
{
return
RaisedButton
(
onPressed:
()
{
showGeneralDialog
<
void
>(
useRootNavigator:
false
,
context:
context
,
barrierDismissible:
false
,
transitionDuration:
Duration
.
zero
,
pageBuilder:
(
BuildContext
innerContext
,
_
,
__
)
{
return
const
SizedBox
();
},
);
},
child:
const
Text
(
'Show Dialog'
),
);
},
);
},
),
));
// Open the dialog.
await
tester
.
tap
(
find
.
byType
(
RaisedButton
));
expect
(
rootObserver
.
dialogCount
,
0
);
expect
(
nestedObserver
.
dialogCount
,
1
);
});
});
});
}
}
...
@@ -805,3 +880,15 @@ class TestPageRouteBuilder extends PageRouteBuilder<void> {
...
@@ -805,3 +880,15 @@ class TestPageRouteBuilder extends PageRouteBuilder<void> {
return
CurvedAnimation
(
parent:
super
.
createAnimation
(),
curve:
Curves
.
easeOutExpo
);
return
CurvedAnimation
(
parent:
super
.
createAnimation
(),
curve:
Curves
.
easeOutExpo
);
}
}
}
}
class
DialogObserver
extends
NavigatorObserver
{
int
dialogCount
=
0
;
@override
void
didPush
(
Route
<
dynamic
>
route
,
Route
<
dynamic
>
previousRoute
)
{
if
(
route
.
toString
().
contains
(
'_DialogRoute'
))
{
dialogCount
++;
}
super
.
didPush
(
route
,
previousRoute
);
}
}
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