From 368537b910d6d066fd6dc014e5a7128d734d2830 Mon Sep 17 00:00:00 2001 From: David Skelly Date: Wed, 22 Feb 2023 20:07:51 -0500 Subject: [PATCH] Add padding to DropdownButton (#115806) * add padding param to DropdownButton * improve padding comment * update test * Add more context to documentation * update padding documentation with more detail --------- Co-authored-by: Kate Lovett --- .../flutter/lib/src/material/dropdown.dart | 17 ++++++++++- .../flutter/test/material/dropdown_test.dart | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart index c85dfc7bfb..d25a784c46 100644 --- a/packages/flutter/lib/src/material/dropdown.dart +++ b/packages/flutter/lib/src/material/dropdown.dart @@ -886,6 +886,7 @@ class DropdownButton extends StatefulWidget { this.enableFeedback, this.alignment = AlignmentDirectional.centerStart, this.borderRadius, + this.padding, // When adding new arguments, consider adding similar arguments to // DropdownButtonFormField. }) : assert(items == null || items.isEmpty || value == null || @@ -929,6 +930,7 @@ class DropdownButton extends StatefulWidget { this.enableFeedback, this.alignment = AlignmentDirectional.centerStart, this.borderRadius, + this.padding, required InputDecoration inputDecoration, required bool isEmpty, required bool isFocused, @@ -1115,6 +1117,17 @@ class DropdownButton extends StatefulWidget { /// instead. final Color? dropdownColor; + /// Padding around the visible portion of the dropdown widget. + /// + /// As the padding increases, the size of the [DropdownButton] will also + /// increase. The padding is included in the clickable area of the dropdown + /// widget, so this can make the widget easier to click. + /// + /// Padding can be useful when used with a custom border. The clickable + /// area will stay flush with the border, as opposed to an external [Padding] + /// widget which will leave a non-clickable gap. + final EdgeInsetsGeometry? padding; + /// The maximum height of the menu. /// /// The maximum height of the menu must be at least one row shorter than @@ -1505,7 +1518,7 @@ class _DropdownButtonState extends State> with WidgetsBindi autofocus: widget.autofocus, focusColor: widget.focusColor ?? Theme.of(context).focusColor, enableFeedback: false, - child: result, + child: widget.padding == null ? result : Padding(padding: widget.padding!, child: result), ), ), ); @@ -1566,6 +1579,7 @@ class DropdownButtonFormField extends FormField { bool? enableFeedback, AlignmentGeometry alignment = AlignmentDirectional.centerStart, BorderRadius? borderRadius, + EdgeInsetsGeometry? padding, // When adding new arguments, consider adding similar arguments to // DropdownButton. }) : assert(items == null || items.isEmpty || value == null || @@ -1635,6 +1649,7 @@ class DropdownButtonFormField extends FormField { inputDecoration: effectiveDecoration.copyWith(errorText: field.errorText), isEmpty: isEmpty, isFocused: Focus.of(context).hasFocus, + padding: padding, ), ); }), diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index c951b1de37..71da466541 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -67,6 +67,7 @@ Widget buildDropdown({ Color? focusColor, Color? dropdownColor, double? menuMaxHeight, + EdgeInsetsGeometry? padding, }) { final List>? listItems = items?.map>((String item) { return DropdownMenuItem( @@ -101,6 +102,7 @@ Widget buildDropdown({ itemHeight: itemHeight, alignment: alignment, menuMaxHeight: menuMaxHeight, + padding: padding, ), ); } @@ -127,6 +129,7 @@ Widget buildDropdown({ itemHeight: itemHeight, alignment: alignment, menuMaxHeight: menuMaxHeight, + padding: padding, ); } @@ -156,6 +159,7 @@ Widget buildFrame({ Color? dropdownColor, bool isFormField = false, double? menuMaxHeight, + EdgeInsetsGeometry? padding, Alignment dropdownAlignment = Alignment.center, }) { return TestApp( @@ -189,6 +193,7 @@ Widget buildFrame({ itemHeight: itemHeight, alignment: alignment, menuMaxHeight: menuMaxHeight, + padding: padding, ), ), ), @@ -3933,4 +3938,28 @@ void main() { final RenderClipRRect renderClip = tester.allRenderObjects.whereType().first; expect(renderClip.borderRadius, BorderRadius.circular(radius)); }); + + testWidgets('Size of DropdownButton with padding', (WidgetTester tester) async { + const double padVertical = 5; + const double padHorizontal = 10; + final Key buttonKey = UniqueKey(); + EdgeInsets? padding; + + Widget build() => buildFrame(buttonKey: buttonKey, onChanged: onChanged, padding: padding); + + await tester.pumpWidget(build()); + final RenderBox buttonBoxNoPadding = tester.renderObject(find.byKey(buttonKey)); + assert(buttonBoxNoPadding.attached); + final Size noPaddingSize = Size.copy(buttonBoxNoPadding.size); + + padding = const EdgeInsets.symmetric(vertical: padVertical, horizontal: padHorizontal); + await tester.pumpWidget(build()); + final RenderBox buttonBoxPadded = tester.renderObject(find.byKey(buttonKey)); + assert(buttonBoxPadded.attached); + final Size paddedSize = Size.copy(buttonBoxPadded.size); + + // dropdowns with padding should be that much larger than with no padding + expect(noPaddingSize.height, equals(paddedSize.height - padVertical * 2)); + expect(noPaddingSize.width, equals(paddedSize.width - padHorizontal * 2)); + }); }