Add flag to use root navigator for showModalBottomSheet (#35878)
* Add flag to use root navigator for showModalBottomSheet * Add documentation * Add tests * Address feedback and fix analyzer issues * Address feedback * Update comments
This commit is contained in:
parent
14e4565fa4
commit
70bb5d1d5a
@ -400,6 +400,11 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
||||
/// a [GridView] and have the bottom sheet be draggable, you should set this
|
||||
/// parameter to true.
|
||||
///
|
||||
/// The `useRootNavigator` parameter ensures that the root navigator is used to
|
||||
/// display the [BottomSheet] when set to `true`. This is useful in the case
|
||||
/// that a modal [BottomSheet] needs to be displayed above all other content
|
||||
/// but the caller is inside another [Navigator].
|
||||
///
|
||||
/// Returns a `Future` that resolves to the value (if any) that was passed to
|
||||
/// [Navigator.pop] when the modal bottom sheet was closed.
|
||||
///
|
||||
@ -417,14 +422,16 @@ Future<T> showModalBottomSheet<T>({
|
||||
double elevation,
|
||||
ShapeBorder shape,
|
||||
bool isScrollControlled = false,
|
||||
bool useRootNavigator = false,
|
||||
}) {
|
||||
assert(context != null);
|
||||
assert(builder != null);
|
||||
assert(isScrollControlled != null);
|
||||
assert(useRootNavigator != null);
|
||||
assert(debugCheckHasMediaQuery(context));
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
return Navigator.push(context, _ModalBottomSheetRoute<T>(
|
||||
return Navigator.of(context, rootNavigator: useRootNavigator).push(_ModalBottomSheetRoute<T>(
|
||||
builder: builder,
|
||||
theme: Theme.of(context, shadowThemeOnly: true),
|
||||
isScrollControlled: isScrollControlled,
|
||||
|
@ -361,4 +361,91 @@ void main() {
|
||||
), ignoreTransform: true, ignoreRect: true, ignoreId: true));
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('showModalBottomSheet does not use root Navigator by default', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Navigator(onGenerateRoute: (RouteSettings settings) => MaterialPageRoute<void>(builder: (_) {
|
||||
return const _TestPage();
|
||||
})),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.ac_unit),
|
||||
title: Text('Item 1'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.style),
|
||||
title: Text('Item 2'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.tap(find.text('Show bottom sheet'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Bottom sheet is displayed in correct position within the inner navigator
|
||||
// and above the BottomNavigationBar.
|
||||
expect(tester.getBottomLeft(find.byType(BottomSheet)).dy, 544.0);
|
||||
});
|
||||
|
||||
testWidgets('showModalBottomSheet uses root Navigator when specified', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Navigator(onGenerateRoute: (RouteSettings settings) => MaterialPageRoute<void>(builder: (_) {
|
||||
return const _TestPage(useRootNavigator: true);
|
||||
})),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.ac_unit),
|
||||
title: Text('Item 1'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.style),
|
||||
title: Text('Item 2'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.tap(find.text('Show bottom sheet'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Bottom sheet is displayed in correct position above all content including
|
||||
// the BottomNavigationBar.
|
||||
expect(tester.getBottomLeft(find.byType(BottomSheet)).dy, 600.0);
|
||||
});
|
||||
}
|
||||
|
||||
class _TestPage extends StatelessWidget {
|
||||
const _TestPage({Key key, this.useRootNavigator}) : super(key: key);
|
||||
|
||||
final bool useRootNavigator;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: FlatButton(
|
||||
child: const Text('Show bottom sheet'),
|
||||
onPressed: () {
|
||||
if (useRootNavigator != null) {
|
||||
showModalBottomSheet<void>(
|
||||
useRootNavigator: useRootNavigator,
|
||||
context: context,
|
||||
builder: (_) => const Text('Modal bottom sheet'),
|
||||
);
|
||||
} else {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (_) => const Text('Modal bottom sheet'),
|
||||
);
|
||||
}
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user