diff --git a/packages/flutter/lib/src/material/bottom_sheet.dart b/packages/flutter/lib/src/material/bottom_sheet.dart index cd7e80a66b4..80e5bdc100e 100644 --- a/packages/flutter/lib/src/material/bottom_sheet.dart +++ b/packages/flutter/lib/src/material/bottom_sheet.dart @@ -427,6 +427,10 @@ class _ModalBottomSheetRoute extends PopupRoute { /// that a modal [BottomSheet] needs to be displayed above all other content /// but the caller is inside another [Navigator]. /// +/// The optional [backgroundColor], [elevation], [shape], and [clipBehavior] +/// parameters can be passed in to customize the appearance and behavior of +/// modal bottom sheets. +/// /// Returns a `Future` that resolves to the value (if any) that was passed to /// [Navigator.pop] when the modal bottom sheet was closed. /// @@ -456,13 +460,15 @@ Future showModalBottomSheet({ assert(debugCheckHasMediaQuery(context)); assert(debugCheckHasMaterialLocalizations(context)); + final BottomSheetThemeData theme = Theme.of(context).bottomSheetTheme; + return Navigator.of(context, rootNavigator: useRootNavigator).push(_ModalBottomSheetRoute( builder: builder, theme: Theme.of(context, shadowThemeOnly: true), isScrollControlled: isScrollControlled, barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, - backgroundColor: backgroundColor, - elevation: elevation ?? Theme.of(context).bottomSheetTheme.modalElevation, + backgroundColor: backgroundColor ?? theme?.modalBackgroundColor ?? theme?.backgroundColor, + elevation: elevation ?? theme?.modalElevation ?? theme?.elevation, shape: shape, clipBehavior: clipBehavior, )); @@ -474,6 +480,10 @@ Future showModalBottomSheet({ /// Returns a controller that can be used to close and otherwise manipulate the /// bottom sheet. /// +/// The optional [backgroundColor], [elevation], [shape], and [clipBehavior] +/// parameters can be passed in to customize the appearance and behavior of +/// persistent bottom sheets. +/// /// To rebuild the bottom sheet (e.g. if it is stateful), call /// [PersistentBottomSheetController.setState] on the controller returned by /// this method. diff --git a/packages/flutter/lib/src/material/bottom_sheet_theme.dart b/packages/flutter/lib/src/material/bottom_sheet_theme.dart index bdb1db5df7b..6207ffaf1bb 100644 --- a/packages/flutter/lib/src/material/bottom_sheet_theme.dart +++ b/packages/flutter/lib/src/material/bottom_sheet_theme.dart @@ -29,6 +29,7 @@ class BottomSheetThemeData extends Diagnosticable { const BottomSheetThemeData({ this.backgroundColor, this.elevation, + this.modalBackgroundColor, this.modalElevation, this.shape, this.clipBehavior, @@ -46,10 +47,12 @@ class BottomSheetThemeData extends Diagnosticable { /// If null, [BottomSheet] defaults to 0.0. final double elevation; + /// Value for [BottomSheet.backgroundColor] when the Bottom sheet is presented + /// as a modal bottom sheet. + final Color modalBackgroundColor; + /// Value for [BottomSheet.elevation] when the Bottom sheet is presented as a /// modal bottom sheet. - /// - /// If null, [BottomSheet.elevation] defaults to [elevation]. final double modalElevation; /// Default value for [BottomSheet.shape]. @@ -68,6 +71,7 @@ class BottomSheetThemeData extends Diagnosticable { BottomSheetThemeData copyWith({ Color backgroundColor, double elevation, + Color modalBackgroundColor, double modalElevation, ShapeBorder shape, Clip clipBehavior, @@ -75,6 +79,7 @@ class BottomSheetThemeData extends Diagnosticable { return BottomSheetThemeData( backgroundColor: backgroundColor ?? this.backgroundColor, elevation: elevation ?? this.elevation, + modalBackgroundColor: modalBackgroundColor ?? this.modalBackgroundColor, modalElevation: modalElevation ?? this.modalElevation, shape: shape ?? this.shape, clipBehavior: clipBehavior ?? this.clipBehavior, @@ -93,6 +98,7 @@ class BottomSheetThemeData extends Diagnosticable { return BottomSheetThemeData( backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), elevation: lerpDouble(a?.elevation, b?.elevation, t), + modalBackgroundColor: Color.lerp(a?.modalBackgroundColor, b?.modalBackgroundColor, t), modalElevation: lerpDouble(a?.modalElevation, b?.modalElevation, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t), clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior, @@ -104,6 +110,7 @@ class BottomSheetThemeData extends Diagnosticable { return hashValues( backgroundColor, elevation, + modalBackgroundColor, modalElevation, shape, clipBehavior, @@ -119,6 +126,7 @@ class BottomSheetThemeData extends Diagnosticable { final BottomSheetThemeData typedOther = other; return typedOther.backgroundColor == backgroundColor && typedOther.elevation == elevation + && typedOther.modalBackgroundColor == modalBackgroundColor && typedOther.modalElevation == modalElevation && typedOther.shape == shape && typedOther.clipBehavior == clipBehavior; @@ -129,6 +137,7 @@ class BottomSheetThemeData extends Diagnosticable { super.debugFillProperties(properties); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null)); properties.add(DoubleProperty('elevation', elevation, defaultValue: null)); + properties.add(ColorProperty('modalBackgroundColor', modalBackgroundColor, defaultValue: null)); properties.add(DoubleProperty('modalElevation', modalElevation, defaultValue: null)); properties.add(DiagnosticsProperty('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty('clipBehavior', clipBehavior, defaultValue: null)); diff --git a/packages/flutter/test/material/bottom_sheet_theme_test.dart b/packages/flutter/test/material/bottom_sheet_theme_test.dart index 893b8edecc1..0553d44f8a1 100644 --- a/packages/flutter/test/material/bottom_sheet_theme_test.dart +++ b/packages/flutter/test/material/bottom_sheet_theme_test.dart @@ -141,12 +141,16 @@ void main() { expect(material.clipBehavior, clipBehavior); }); - testWidgets('BottomSheetThemeData.modalElevation takes priority over BottomSheetThemeData.elevation for modal bottom sheets', (WidgetTester tester) async { + testWidgets('Modal bottom sheet-specific parameters are used for modal bottom sheets', (WidgetTester tester) async { const double modalElevation = 5.0; const double persistentElevation = 7.0; + const Color modalBackgroundColor = Colors.yellow; + const Color persistentBackgroundColor = Colors.red; const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( elevation: persistentElevation, modalElevation: modalElevation, + backgroundColor: persistentBackgroundColor, + modalBackgroundColor: modalBackgroundColor, ); await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); @@ -160,14 +164,19 @@ void main() { ), ); expect(material.elevation, modalElevation); + expect(material.color, modalBackgroundColor); }); - testWidgets('BottomSheetThemeData.elevation takes priority over BottomSheetThemeData.modalElevation for peristent bottom sheets', (WidgetTester tester) async { + testWidgets('General bottom sheet parameters take priority over modal bottom sheet-specific parameters for peristent bottom sheets', (WidgetTester tester) async { const double modalElevation = 5.0; const double persistentElevation = 7.0; + const Color modalBackgroundColor = Colors.yellow; + const Color persistentBackgroundColor = Colors.red; const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( elevation: persistentElevation, modalElevation: modalElevation, + backgroundColor: persistentBackgroundColor, + modalBackgroundColor: modalBackgroundColor, ); await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); @@ -181,12 +190,15 @@ void main() { ), ); expect(material.elevation, persistentElevation); + expect(material.color, persistentBackgroundColor); }); - testWidgets('BottomSheetThemeData.modalElevation doesn\'t apply to persistent bottom sheets', (WidgetTester tester) async { + testWidgets('Modal bottom sheet-specific parameters don\'t apply to persistent bottom sheets', (WidgetTester tester) async { const double modalElevation = 5.0; + const Color modalBackgroundColor = Colors.yellow; const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( modalElevation: modalElevation, + modalBackgroundColor: modalBackgroundColor, ); await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); @@ -200,6 +212,7 @@ void main() { ), ); expect(material.elevation, 0); + expect(material.color, null); }); }