mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Added the ability to constrain the size of bottom sheets. (#80527)
This commit is contained in:
parent
21fd5cdd1a
commit
746ce203d2
@ -78,6 +78,7 @@ class BottomSheet extends StatefulWidget {
|
|||||||
this.elevation,
|
this.elevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
|
this.constraints,
|
||||||
required this.onClosing,
|
required this.onClosing,
|
||||||
required this.builder,
|
required this.builder,
|
||||||
}) : assert(enableDrag != null),
|
}) : assert(enableDrag != null),
|
||||||
@ -162,6 +163,23 @@ class BottomSheet extends StatefulWidget {
|
|||||||
/// will be [Clip.none].
|
/// will be [Clip.none].
|
||||||
final Clip? clipBehavior;
|
final Clip? clipBehavior;
|
||||||
|
|
||||||
|
/// Defines minimum and maximum sizes for a [BottomSheet].
|
||||||
|
///
|
||||||
|
/// Typically a bottom sheet will cover the entire width of its
|
||||||
|
/// parent. However for large screens you may want to limit the width
|
||||||
|
/// to something smaller and this property provides a way to specify
|
||||||
|
/// a maximum width.
|
||||||
|
///
|
||||||
|
/// If null, then the ambient [ThemeData.bottomSheetTheme]'s
|
||||||
|
/// [BottomSheetThemeData.constraints] will be used. If that
|
||||||
|
/// is null then the bottom sheet's size will be constrained
|
||||||
|
/// by its parent (usually a [Scaffold]).
|
||||||
|
///
|
||||||
|
/// If constraints are specified (either in this property or in the
|
||||||
|
/// theme), the bottom sheet will be aligned to the bottom-center of
|
||||||
|
/// the available space. Otherwise, no alignment is applied.
|
||||||
|
final BoxConstraints? constraints;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BottomSheetState createState() => _BottomSheetState();
|
_BottomSheetState createState() => _BottomSheetState();
|
||||||
|
|
||||||
@ -244,12 +262,13 @@ class _BottomSheetState extends State<BottomSheet> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final BottomSheetThemeData bottomSheetTheme = Theme.of(context).bottomSheetTheme;
|
final BottomSheetThemeData bottomSheetTheme = Theme.of(context).bottomSheetTheme;
|
||||||
|
final BoxConstraints? constraints = widget.constraints ?? bottomSheetTheme.constraints;
|
||||||
final Color? color = widget.backgroundColor ?? bottomSheetTheme.backgroundColor;
|
final Color? color = widget.backgroundColor ?? bottomSheetTheme.backgroundColor;
|
||||||
final double elevation = widget.elevation ?? bottomSheetTheme.elevation ?? 0;
|
final double elevation = widget.elevation ?? bottomSheetTheme.elevation ?? 0;
|
||||||
final ShapeBorder? shape = widget.shape ?? bottomSheetTheme.shape;
|
final ShapeBorder? shape = widget.shape ?? bottomSheetTheme.shape;
|
||||||
final Clip clipBehavior = widget.clipBehavior ?? bottomSheetTheme.clipBehavior ?? Clip.none;
|
final Clip clipBehavior = widget.clipBehavior ?? bottomSheetTheme.clipBehavior ?? Clip.none;
|
||||||
|
|
||||||
final Widget bottomSheet = Material(
|
Widget bottomSheet = Material(
|
||||||
key: _childKey,
|
key: _childKey,
|
||||||
color: color,
|
color: color,
|
||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
@ -260,6 +279,17 @@ class _BottomSheetState extends State<BottomSheet> {
|
|||||||
child: widget.builder(context),
|
child: widget.builder(context),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (constraints != null) {
|
||||||
|
bottomSheet = Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: constraints,
|
||||||
|
child: bottomSheet,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return !widget.enableDrag ? bottomSheet : GestureDetector(
|
return !widget.enableDrag ? bottomSheet : GestureDetector(
|
||||||
onVerticalDragStart: _handleDragStart,
|
onVerticalDragStart: _handleDragStart,
|
||||||
onVerticalDragUpdate: _handleDragUpdate,
|
onVerticalDragUpdate: _handleDragUpdate,
|
||||||
@ -313,6 +343,7 @@ class _ModalBottomSheet<T> extends StatefulWidget {
|
|||||||
this.elevation,
|
this.elevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
|
this.constraints,
|
||||||
this.isScrollControlled = false,
|
this.isScrollControlled = false,
|
||||||
this.enableDrag = true,
|
this.enableDrag = true,
|
||||||
}) : assert(isScrollControlled != null),
|
}) : assert(isScrollControlled != null),
|
||||||
@ -325,6 +356,7 @@ class _ModalBottomSheet<T> extends StatefulWidget {
|
|||||||
final double? elevation;
|
final double? elevation;
|
||||||
final ShapeBorder? shape;
|
final ShapeBorder? shape;
|
||||||
final Clip? clipBehavior;
|
final Clip? clipBehavior;
|
||||||
|
final BoxConstraints? constraints;
|
||||||
final bool enableDrag;
|
final bool enableDrag;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -382,6 +414,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
|
|||||||
elevation: widget.elevation,
|
elevation: widget.elevation,
|
||||||
shape: widget.shape,
|
shape: widget.shape,
|
||||||
clipBehavior: widget.clipBehavior,
|
clipBehavior: widget.clipBehavior,
|
||||||
|
constraints: widget.constraints,
|
||||||
enableDrag: widget.enableDrag,
|
enableDrag: widget.enableDrag,
|
||||||
onDragStart: handleDragStart,
|
onDragStart: handleDragStart,
|
||||||
onDragEnd: handleDragEnd,
|
onDragEnd: handleDragEnd,
|
||||||
@ -418,6 +451,7 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||||||
this.elevation,
|
this.elevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
|
this.constraints,
|
||||||
this.modalBarrierColor,
|
this.modalBarrierColor,
|
||||||
this.isDismissible = true,
|
this.isDismissible = true,
|
||||||
this.enableDrag = true,
|
this.enableDrag = true,
|
||||||
@ -436,6 +470,7 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||||||
final double? elevation;
|
final double? elevation;
|
||||||
final ShapeBorder? shape;
|
final ShapeBorder? shape;
|
||||||
final Clip? clipBehavior;
|
final Clip? clipBehavior;
|
||||||
|
final BoxConstraints? constraints;
|
||||||
final Color? modalBarrierColor;
|
final Color? modalBarrierColor;
|
||||||
final bool isDismissible;
|
final bool isDismissible;
|
||||||
final bool enableDrag;
|
final bool enableDrag;
|
||||||
@ -481,6 +516,7 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||||||
elevation: elevation ?? sheetTheme.modalElevation ?? sheetTheme.elevation,
|
elevation: elevation ?? sheetTheme.modalElevation ?? sheetTheme.elevation,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
|
constraints: constraints,
|
||||||
isScrollControlled: isScrollControlled,
|
isScrollControlled: isScrollControlled,
|
||||||
enableDrag: enableDrag,
|
enableDrag: enableDrag,
|
||||||
);
|
);
|
||||||
@ -582,9 +618,11 @@ class _BottomSheetSuspendedCurve extends ParametricCurve<double> {
|
|||||||
/// The [enableDrag] parameter specifies whether the bottom sheet can be
|
/// The [enableDrag] parameter specifies whether the bottom sheet can be
|
||||||
/// dragged up and down and dismissed by swiping downwards.
|
/// dragged up and down and dismissed by swiping downwards.
|
||||||
///
|
///
|
||||||
/// The optional [backgroundColor], [elevation], [shape], [clipBehavior] and [transitionAnimationController]
|
/// The optional [backgroundColor], [elevation], [shape], [clipBehavior],
|
||||||
|
/// [constraints] and [transitionAnimationController]
|
||||||
/// parameters can be passed in to customize the appearance and behavior of
|
/// parameters can be passed in to customize the appearance and behavior of
|
||||||
/// modal bottom sheets.
|
/// modal bottom sheets (see the documentation for these on [BottomSheet]
|
||||||
|
/// for more details).
|
||||||
///
|
///
|
||||||
/// The [transitionAnimationController] controls the bottom sheet's entrance and
|
/// The [transitionAnimationController] controls the bottom sheet's entrance and
|
||||||
/// exit animations if provided.
|
/// exit animations if provided.
|
||||||
@ -653,6 +691,7 @@ Future<T?> showModalBottomSheet<T>({
|
|||||||
double? elevation,
|
double? elevation,
|
||||||
ShapeBorder? shape,
|
ShapeBorder? shape,
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
|
BoxConstraints? constraints,
|
||||||
Color? barrierColor,
|
Color? barrierColor,
|
||||||
bool isScrollControlled = false,
|
bool isScrollControlled = false,
|
||||||
bool useRootNavigator = false,
|
bool useRootNavigator = false,
|
||||||
@ -680,6 +719,7 @@ Future<T?> showModalBottomSheet<T>({
|
|||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
|
constraints: constraints,
|
||||||
isDismissible: isDismissible,
|
isDismissible: isDismissible,
|
||||||
modalBarrierColor: barrierColor,
|
modalBarrierColor: barrierColor,
|
||||||
enableDrag: enableDrag,
|
enableDrag: enableDrag,
|
||||||
@ -694,9 +734,11 @@ Future<T?> showModalBottomSheet<T>({
|
|||||||
/// Returns a controller that can be used to close and otherwise manipulate the
|
/// Returns a controller that can be used to close and otherwise manipulate the
|
||||||
/// bottom sheet.
|
/// bottom sheet.
|
||||||
///
|
///
|
||||||
/// The optional [backgroundColor], [elevation], [shape], [clipBehavior] and [transitionAnimationController]
|
/// The optional [backgroundColor], [elevation], [shape], [clipBehavior],
|
||||||
|
/// [constraints] and [transitionAnimationController]
|
||||||
/// parameters can be passed in to customize the appearance and behavior of
|
/// parameters can be passed in to customize the appearance and behavior of
|
||||||
/// persistent bottom sheets.
|
/// persistent bottom sheets (see the documentation for these on [BottomSheet]
|
||||||
|
/// for more details).
|
||||||
///
|
///
|
||||||
/// To rebuild the bottom sheet (e.g. if it is stateful), call
|
/// To rebuild the bottom sheet (e.g. if it is stateful), call
|
||||||
/// [PersistentBottomSheetController.setState] on the controller returned by
|
/// [PersistentBottomSheetController.setState] on the controller returned by
|
||||||
@ -734,6 +776,7 @@ PersistentBottomSheetController<T> showBottomSheet<T>({
|
|||||||
double? elevation,
|
double? elevation,
|
||||||
ShapeBorder? shape,
|
ShapeBorder? shape,
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
|
BoxConstraints? constraints,
|
||||||
AnimationController? transitionAnimationController,
|
AnimationController? transitionAnimationController,
|
||||||
}) {
|
}) {
|
||||||
assert(context != null);
|
assert(context != null);
|
||||||
@ -746,6 +789,7 @@ PersistentBottomSheetController<T> showBottomSheet<T>({
|
|||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
|
constraints: constraints,
|
||||||
transitionAnimationController: transitionAnimationController,
|
transitionAnimationController: transitionAnimationController,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
this.modalElevation,
|
this.modalElevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
|
this.constraints,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Default value for [BottomSheet.backgroundColor].
|
/// Default value for [BottomSheet.backgroundColor].
|
||||||
@ -67,6 +68,11 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
/// If null, [BottomSheet] uses [Clip.none].
|
/// If null, [BottomSheet] uses [Clip.none].
|
||||||
final Clip? clipBehavior;
|
final Clip? clipBehavior;
|
||||||
|
|
||||||
|
/// Constrains the size of the [BottomSheet].
|
||||||
|
///
|
||||||
|
/// If null, the bottom sheet's size will be unconstrained.
|
||||||
|
final BoxConstraints? constraints;
|
||||||
|
|
||||||
/// Creates a copy of this object with the given fields replaced with the
|
/// Creates a copy of this object with the given fields replaced with the
|
||||||
/// new values.
|
/// new values.
|
||||||
BottomSheetThemeData copyWith({
|
BottomSheetThemeData copyWith({
|
||||||
@ -76,6 +82,7 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
double? modalElevation,
|
double? modalElevation,
|
||||||
ShapeBorder? shape,
|
ShapeBorder? shape,
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
|
BoxConstraints? constraints,
|
||||||
}) {
|
}) {
|
||||||
return BottomSheetThemeData(
|
return BottomSheetThemeData(
|
||||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||||
@ -84,6 +91,7 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
modalElevation: modalElevation ?? this.modalElevation,
|
modalElevation: modalElevation ?? this.modalElevation,
|
||||||
shape: shape ?? this.shape,
|
shape: shape ?? this.shape,
|
||||||
clipBehavior: clipBehavior ?? this.clipBehavior,
|
clipBehavior: clipBehavior ?? this.clipBehavior,
|
||||||
|
constraints: constraints ?? this.constraints,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +111,7 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
modalElevation: lerpDouble(a?.modalElevation, b?.modalElevation, t),
|
modalElevation: lerpDouble(a?.modalElevation, b?.modalElevation, t),
|
||||||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
|
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
|
||||||
clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior,
|
clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior,
|
||||||
|
constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +124,7 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
modalElevation,
|
modalElevation,
|
||||||
shape,
|
shape,
|
||||||
clipBehavior,
|
clipBehavior,
|
||||||
|
constraints,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +140,8 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
&& other.modalBackgroundColor == modalBackgroundColor
|
&& other.modalBackgroundColor == modalBackgroundColor
|
||||||
&& other.modalElevation == modalElevation
|
&& other.modalElevation == modalElevation
|
||||||
&& other.shape == shape
|
&& other.shape == shape
|
||||||
&& other.clipBehavior == clipBehavior;
|
&& other.clipBehavior == clipBehavior
|
||||||
|
&& other.constraints == constraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -142,5 +153,6 @@ class BottomSheetThemeData with Diagnosticable {
|
|||||||
properties.add(DoubleProperty('modalElevation', modalElevation, defaultValue: null));
|
properties.add(DoubleProperty('modalElevation', modalElevation, defaultValue: null));
|
||||||
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
|
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
|
||||||
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
|
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
|
||||||
|
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2481,6 +2481,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
|||||||
double? elevation,
|
double? elevation,
|
||||||
ShapeBorder? shape,
|
ShapeBorder? shape,
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
|
BoxConstraints? constraints,
|
||||||
}) {
|
}) {
|
||||||
assert(() {
|
assert(() {
|
||||||
if (widget.bottomSheet != null && isPersistent && _currentBottomSheet != null) {
|
if (widget.bottomSheet != null && isPersistent && _currentBottomSheet != null) {
|
||||||
@ -2554,6 +2555,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
|||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
|
constraints: constraints,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isPersistent)
|
if (!isPersistent)
|
||||||
@ -2653,6 +2655,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
|||||||
double? elevation,
|
double? elevation,
|
||||||
ShapeBorder? shape,
|
ShapeBorder? shape,
|
||||||
Clip? clipBehavior,
|
Clip? clipBehavior,
|
||||||
|
BoxConstraints? constraints,
|
||||||
AnimationController? transitionAnimationController,
|
AnimationController? transitionAnimationController,
|
||||||
}) {
|
}) {
|
||||||
assert(() {
|
assert(() {
|
||||||
@ -2678,6 +2681,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
|||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
|
constraints: constraints,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return _currentBottomSheet! as PersistentBottomSheetController<T>;
|
return _currentBottomSheet! as PersistentBottomSheetController<T>;
|
||||||
@ -3356,6 +3360,7 @@ class _StandardBottomSheet extends StatefulWidget {
|
|||||||
this.elevation,
|
this.elevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
|
this.constraints,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final AnimationController animationController; // we control it, but it must be disposed by whoever created it.
|
final AnimationController animationController; // we control it, but it must be disposed by whoever created it.
|
||||||
@ -3368,6 +3373,7 @@ class _StandardBottomSheet extends StatefulWidget {
|
|||||||
final double? elevation;
|
final double? elevation;
|
||||||
final ShapeBorder? shape;
|
final ShapeBorder? shape;
|
||||||
final Clip? clipBehavior;
|
final Clip? clipBehavior;
|
||||||
|
final BoxConstraints? constraints;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StandardBottomSheetState createState() => _StandardBottomSheetState();
|
_StandardBottomSheetState createState() => _StandardBottomSheetState();
|
||||||
@ -3472,6 +3478,7 @@ class _StandardBottomSheetState extends State<_StandardBottomSheet> {
|
|||||||
elevation: widget.elevation,
|
elevation: widget.elevation,
|
||||||
shape: widget.shape,
|
shape: widget.shape,
|
||||||
clipBehavior: widget.clipBehavior,
|
clipBehavior: widget.clipBehavior,
|
||||||
|
constraints: widget.constraints,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -833,6 +833,219 @@ void main() {
|
|||||||
// The bottom sheet should not be showing any longer.
|
// The bottom sheet should not be showing any longer.
|
||||||
expect(find.text('BottomSheet'), findsNothing);
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('constraints', () {
|
||||||
|
|
||||||
|
testWidgets('No constraints by default for bottomSheet property', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(const MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(child: Text('body')),
|
||||||
|
bottomSheet: Text('BottomSheet'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(0, 586, 154, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('No constraints by default for showBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
Scaffold.of(context).showBottomSheet<void>(
|
||||||
|
(BuildContext context) => const Text('BottomSheet')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(0, 586, 154, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('No constraints by default for showModalBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(0, 586, 800, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Theme constraints used for bottomSheet property', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
|
constraints: BoxConstraints(maxWidth: 80),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
home: const Scaffold(
|
||||||
|
body: Center(child: Text('body')),
|
||||||
|
bottomSheet: Text('BottomSheet'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
// Should be centered and only 80dp wide
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(360, 558, 440, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Theme constraints used for showBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
|
constraints: BoxConstraints(maxWidth: 80),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
Scaffold.of(context).showBottomSheet<void>(
|
||||||
|
(BuildContext context) => const Text('BottomSheet')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
// Should be centered and only 80dp wide
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(360, 558, 440, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Theme constraints used for showModalBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
|
constraints: BoxConstraints(maxWidth: 80),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
// Should be centered and only 80dp wide
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(360, 558, 440, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('constraints param overrides theme for showBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
|
constraints: BoxConstraints(maxWidth: 80),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
Scaffold.of(context).showBottomSheet<void>(
|
||||||
|
(BuildContext context) => const Text('BottomSheet'),
|
||||||
|
constraints: const BoxConstraints(maxWidth: 100),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
// Should be centered and only 100dp wide instead of 80dp wide
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(350, 572, 450, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('constraints param overrides theme for showModalBottomSheet', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
|
constraints: BoxConstraints(maxWidth: 80),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Builder(builder: (BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Press me'),
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||||
|
constraints: const BoxConstraints(maxWidth: 100),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
expect(find.text('BottomSheet'), findsNothing);
|
||||||
|
await tester.tap(find.text('Press me'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BottomSheet'), findsOneWidget);
|
||||||
|
// Should be centered and only 100dp instead of 80dp wide
|
||||||
|
expect(tester.getRect(find.text('BottomSheet')),
|
||||||
|
const Rect.fromLTRB(350, 572, 450, 600));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TestPage extends StatelessWidget {
|
class _TestPage extends StatelessWidget {
|
||||||
|
@ -18,6 +18,7 @@ void main() {
|
|||||||
expect(bottomSheetTheme.elevation, null);
|
expect(bottomSheetTheme.elevation, null);
|
||||||
expect(bottomSheetTheme.shape, null);
|
expect(bottomSheetTheme.shape, null);
|
||||||
expect(bottomSheetTheme.clipBehavior, null);
|
expect(bottomSheetTheme.clipBehavior, null);
|
||||||
|
expect(bottomSheetTheme.constraints, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Default BottomSheetThemeData debugFillProperties', (WidgetTester tester) async {
|
testWidgets('Default BottomSheetThemeData debugFillProperties', (WidgetTester tester) async {
|
||||||
@ -39,6 +40,7 @@ void main() {
|
|||||||
elevation: 2.0,
|
elevation: 2.0,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)),
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
|
constraints: const BoxConstraints(minWidth: 200, maxWidth: 640),
|
||||||
).debugFillProperties(builder);
|
).debugFillProperties(builder);
|
||||||
|
|
||||||
final List<String> description = builder.properties
|
final List<String> description = builder.properties
|
||||||
@ -51,6 +53,7 @@ void main() {
|
|||||||
'elevation: 2.0',
|
'elevation: 2.0',
|
||||||
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
|
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
|
||||||
'clipBehavior: Clip.antiAlias',
|
'clipBehavior: Clip.antiAlias',
|
||||||
|
'constraints: BoxConstraints(200.0<=w<=640.0, 0.0<=h<=Infinity)',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user