Skip to content

Commit 368537b

Browse files
davidskellyPiinks
andauthored
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 <katelovett@google.com>
1 parent f85a75d commit 368537b

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

packages/flutter/lib/src/material/dropdown.dart

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ class DropdownButton<T> extends StatefulWidget {
886886
this.enableFeedback,
887887
this.alignment = AlignmentDirectional.centerStart,
888888
this.borderRadius,
889+
this.padding,
889890
// When adding new arguments, consider adding similar arguments to
890891
// DropdownButtonFormField.
891892
}) : assert(items == null || items.isEmpty || value == null ||
@@ -929,6 +930,7 @@ class DropdownButton<T> extends StatefulWidget {
929930
this.enableFeedback,
930931
this.alignment = AlignmentDirectional.centerStart,
931932
this.borderRadius,
933+
this.padding,
932934
required InputDecoration inputDecoration,
933935
required bool isEmpty,
934936
required bool isFocused,
@@ -1115,6 +1117,17 @@ class DropdownButton<T> extends StatefulWidget {
11151117
/// instead.
11161118
final Color? dropdownColor;
11171119

1120+
/// Padding around the visible portion of the dropdown widget.
1121+
///
1122+
/// As the padding increases, the size of the [DropdownButton] will also
1123+
/// increase. The padding is included in the clickable area of the dropdown
1124+
/// widget, so this can make the widget easier to click.
1125+
///
1126+
/// Padding can be useful when used with a custom border. The clickable
1127+
/// area will stay flush with the border, as opposed to an external [Padding]
1128+
/// widget which will leave a non-clickable gap.
1129+
final EdgeInsetsGeometry? padding;
1130+
11181131
/// The maximum height of the menu.
11191132
///
11201133
/// The maximum height of the menu must be at least one row shorter than
@@ -1505,7 +1518,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
15051518
autofocus: widget.autofocus,
15061519
focusColor: widget.focusColor ?? Theme.of(context).focusColor,
15071520
enableFeedback: false,
1508-
child: result,
1521+
child: widget.padding == null ? result : Padding(padding: widget.padding!, child: result),
15091522
),
15101523
),
15111524
);
@@ -1566,6 +1579,7 @@ class DropdownButtonFormField<T> extends FormField<T> {
15661579
bool? enableFeedback,
15671580
AlignmentGeometry alignment = AlignmentDirectional.centerStart,
15681581
BorderRadius? borderRadius,
1582+
EdgeInsetsGeometry? padding,
15691583
// When adding new arguments, consider adding similar arguments to
15701584
// DropdownButton.
15711585
}) : assert(items == null || items.isEmpty || value == null ||
@@ -1635,6 +1649,7 @@ class DropdownButtonFormField<T> extends FormField<T> {
16351649
inputDecoration: effectiveDecoration.copyWith(errorText: field.errorText),
16361650
isEmpty: isEmpty,
16371651
isFocused: Focus.of(context).hasFocus,
1652+
padding: padding,
16381653
),
16391654
);
16401655
}),

packages/flutter/test/material/dropdown_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ Widget buildDropdown({
6767
Color? focusColor,
6868
Color? dropdownColor,
6969
double? menuMaxHeight,
70+
EdgeInsetsGeometry? padding,
7071
}) {
7172
final List<DropdownMenuItem<String>>? listItems = items?.map<DropdownMenuItem<String>>((String item) {
7273
return DropdownMenuItem<String>(
@@ -101,6 +102,7 @@ Widget buildDropdown({
101102
itemHeight: itemHeight,
102103
alignment: alignment,
103104
menuMaxHeight: menuMaxHeight,
105+
padding: padding,
104106
),
105107
);
106108
}
@@ -127,6 +129,7 @@ Widget buildDropdown({
127129
itemHeight: itemHeight,
128130
alignment: alignment,
129131
menuMaxHeight: menuMaxHeight,
132+
padding: padding,
130133
);
131134
}
132135

@@ -156,6 +159,7 @@ Widget buildFrame({
156159
Color? dropdownColor,
157160
bool isFormField = false,
158161
double? menuMaxHeight,
162+
EdgeInsetsGeometry? padding,
159163
Alignment dropdownAlignment = Alignment.center,
160164
}) {
161165
return TestApp(
@@ -189,6 +193,7 @@ Widget buildFrame({
189193
itemHeight: itemHeight,
190194
alignment: alignment,
191195
menuMaxHeight: menuMaxHeight,
196+
padding: padding,
192197
),
193198
),
194199
),
@@ -3933,4 +3938,28 @@ void main() {
39333938
final RenderClipRRect renderClip = tester.allRenderObjects.whereType<RenderClipRRect>().first;
39343939
expect(renderClip.borderRadius, BorderRadius.circular(radius));
39353940
});
3941+
3942+
testWidgets('Size of DropdownButton with padding', (WidgetTester tester) async {
3943+
const double padVertical = 5;
3944+
const double padHorizontal = 10;
3945+
final Key buttonKey = UniqueKey();
3946+
EdgeInsets? padding;
3947+
3948+
Widget build() => buildFrame(buttonKey: buttonKey, onChanged: onChanged, padding: padding);
3949+
3950+
await tester.pumpWidget(build());
3951+
final RenderBox buttonBoxNoPadding = tester.renderObject<RenderBox>(find.byKey(buttonKey));
3952+
assert(buttonBoxNoPadding.attached);
3953+
final Size noPaddingSize = Size.copy(buttonBoxNoPadding.size);
3954+
3955+
padding = const EdgeInsets.symmetric(vertical: padVertical, horizontal: padHorizontal);
3956+
await tester.pumpWidget(build());
3957+
final RenderBox buttonBoxPadded = tester.renderObject<RenderBox>(find.byKey(buttonKey));
3958+
assert(buttonBoxPadded.attached);
3959+
final Size paddedSize = Size.copy(buttonBoxPadded.size);
3960+
3961+
// dropdowns with padding should be that much larger than with no padding
3962+
expect(noPaddingSize.height, equals(paddedSize.height - padVertical * 2));
3963+
expect(noPaddingSize.width, equals(paddedSize.width - padHorizontal * 2));
3964+
});
39363965
}

0 commit comments

Comments
 (0)