Skip to content

Commit bbec650

Browse files
authored
DropdownButton: Fix hint alignment when selectedItemBuilder is non-null. (#106731)
1 parent cf34225 commit bbec650

File tree

2 files changed

+190
-96
lines changed

2 files changed

+190
-96
lines changed

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -1397,17 +1397,17 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
13971397

13981398
int? hintIndex;
13991399
if (widget.hint != null || (!_enabled && widget.disabledHint != null)) {
1400-
Widget displayedHint = _enabled ? widget.hint! : widget.disabledHint ?? widget.hint!;
1401-
if (widget.selectedItemBuilder == null) {
1402-
displayedHint = _DropdownMenuItemContainer(alignment: widget.alignment, child: displayedHint);
1403-
}
1400+
final Widget displayedHint = _enabled ? widget.hint! : widget.disabledHint ?? widget.hint!;
14041401

14051402
hintIndex = items.length;
14061403
items.add(DefaultTextStyle(
14071404
style: _textStyle!.copyWith(color: Theme.of(context).hintColor),
14081405
child: IgnorePointer(
14091406
ignoringSemantics: false,
1410-
child: displayedHint,
1407+
child: _DropdownMenuItemContainer(
1408+
alignment: widget.alignment,
1409+
child: displayedHint,
1410+
),
14111411
),
14121412
));
14131413
}

packages/flutter/test/material/dropdown_test.dart

+185-91
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,30 @@ Widget buildFrame({
195195
);
196196
}
197197

198+
Widget buildDropdownWithHint({
199+
required AlignmentDirectional alignment,
200+
required bool isExpanded,
201+
bool enableSelectedItemBuilder = false,
202+
}){
203+
return buildFrame(
204+
mediaSize: const Size(800, 600),
205+
itemHeight: 100.0,
206+
alignment: alignment,
207+
isExpanded: isExpanded,
208+
selectedItemBuilder: enableSelectedItemBuilder
209+
? (BuildContext context) {
210+
return menuItems.map<Widget>((String item) {
211+
return Container(
212+
color: const Color(0xff00ff00),
213+
child: Text(item),
214+
);
215+
}).toList();
216+
}
217+
: null,
218+
hint: const Text('hint'),
219+
);
220+
}
221+
198222
class TestApp extends StatefulWidget {
199223
const TestApp({
200224
super.key,
@@ -3657,155 +3681,225 @@ void main() {
36573681
});
36583682

36593683
testWidgets('DropdownButton hint alignment', (WidgetTester tester) async {
3660-
final Key buttonKey = UniqueKey();
36613684
const String hintText = 'hint';
36623685

3663-
// DropdownButton with `isExpanded: false` (default)
36643686
// AlignmentDirectional.centerStart (default)
3665-
await tester.pumpWidget(buildFrame(
3666-
buttonKey: buttonKey,
3667-
mediaSize: const Size(800, 600),
3668-
itemHeight: 100.0,
3669-
hint: const Text(hintText)),
3670-
);
3687+
await tester.pumpWidget(buildDropdownWithHint(
3688+
alignment: AlignmentDirectional.centerStart,
3689+
isExpanded: false,
3690+
));
36713691
expect(tester.getTopLeft(find.text(hintText)).dx, 348.0);
36723692
expect(tester.getTopLeft(find.text(hintText)).dy, 292.0);
36733693
// AlignmentDirectional.topStart
3674-
await tester.pumpWidget(buildFrame(
3675-
buttonKey: buttonKey,
3676-
mediaSize: const Size(800, 600),
3694+
await tester.pumpWidget(buildDropdownWithHint(
36773695
alignment: AlignmentDirectional.topStart,
3678-
itemHeight: 100.0,
3679-
hint: const Text(hintText)),
3680-
);
3696+
isExpanded: false,
3697+
));
36813698
expect(tester.getTopLeft(find.text(hintText)).dx, 348.0);
36823699
expect(tester.getTopLeft(find.text(hintText)).dy, 250.0);
36833700
// AlignmentDirectional.bottomStart
3684-
await tester.pumpWidget(buildFrame(
3685-
buttonKey: buttonKey,
3686-
mediaSize: const Size(800, 600),
3701+
await tester.pumpWidget(buildDropdownWithHint(
36873702
alignment: AlignmentDirectional.bottomStart,
3688-
itemHeight: 100.0,
3689-
hint: const Text(hintText)),
3690-
);
3703+
isExpanded: false,
3704+
));
36913705
expect(tester.getBottomLeft(find.text(hintText)).dx, 348.0);
36923706
expect(tester.getBottomLeft(find.text(hintText)).dy, 350.0);
36933707
// AlignmentDirectional.center
3694-
await tester.pumpWidget(buildFrame(
3695-
buttonKey: buttonKey,
3696-
mediaSize: const Size(800, 600),
3708+
await tester.pumpWidget(buildDropdownWithHint(
36973709
alignment: AlignmentDirectional.center,
3698-
itemHeight: 100.0,
3699-
hint: const Text(hintText)),
3700-
);
3710+
isExpanded: false,
3711+
));
37013712
expect(tester.getCenter(find.text(hintText)).dx, 388.0);
37023713
expect(tester.getCenter(find.text(hintText)).dy, 300.0);
37033714
// AlignmentDirectional.topEnd
3704-
await tester.pumpWidget(buildFrame(
3705-
buttonKey: buttonKey,
3706-
mediaSize: const Size(800, 600),
3715+
await tester.pumpWidget(buildDropdownWithHint(
37073716
alignment: AlignmentDirectional.topEnd,
3708-
itemHeight: 100.0,
3709-
hint: const Text(hintText)),
3710-
);
3717+
isExpanded: false,
3718+
));
37113719
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
37123720
expect(tester.getTopRight(find.text(hintText)).dy, 250.0);
37133721
// AlignmentDirectional.centerEnd
3714-
await tester.pumpWidget(buildFrame(
3715-
buttonKey: buttonKey,
3716-
mediaSize: const Size(800, 600),
3722+
await tester.pumpWidget(buildDropdownWithHint(
37173723
alignment: AlignmentDirectional.centerEnd,
3718-
itemHeight: 100.0,
3719-
hint: const Text(hintText)),
3720-
);
3724+
isExpanded: false,
3725+
));
37213726
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
37223727
expect(tester.getTopRight(find.text(hintText)).dy, 292.0);
3723-
// AlignmentDirectional.topEnd
3724-
await tester.pumpWidget(buildFrame(
3725-
buttonKey: buttonKey,
3726-
mediaSize: const Size(800, 600),
3728+
// AlignmentDirectional.bottomEnd
3729+
await tester.pumpWidget(buildDropdownWithHint(
37273730
alignment: AlignmentDirectional.bottomEnd,
3728-
itemHeight: 100.0,
3729-
hint: const Text(hintText)),
3730-
);
3731+
isExpanded: false,
3732+
));
37313733
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
37323734
expect(tester.getTopRight(find.text(hintText)).dy, 334.0);
37333735

37343736
// DropdownButton with `isExpanded: true`
37353737
// AlignmentDirectional.centerStart (default)
3736-
await tester.pumpWidget(buildFrame(
3737-
buttonKey: buttonKey,
3738-
mediaSize: const Size(800, 600),
3739-
itemHeight: 100.0,
3738+
await tester.pumpWidget(buildDropdownWithHint(
3739+
alignment: AlignmentDirectional.centerStart,
37403740
isExpanded: true,
3741-
hint: const Text(hintText)),
3742-
);
3741+
));
37433742
expect(tester.getTopLeft(find.text(hintText)).dx, 0.0);
37443743
expect(tester.getTopLeft(find.text(hintText)).dy, 292.0);
37453744
// AlignmentDirectional.topStart
3746-
await tester.pumpWidget(buildFrame(
3747-
buttonKey: buttonKey,
3748-
mediaSize: const Size(800, 600),
3749-
itemHeight: 100.0,
3750-
isExpanded: true,
3745+
await tester.pumpWidget(buildDropdownWithHint(
37513746
alignment: AlignmentDirectional.topStart,
3752-
hint: const Text(hintText)),
3753-
);
3747+
isExpanded: true,
3748+
));
37543749
expect(tester.getTopLeft(find.text(hintText)).dx, 0.0);
37553750
expect(tester.getTopLeft(find.text(hintText)).dy, 250.0);
37563751
// AlignmentDirectional.bottomStart
3757-
await tester.pumpWidget(buildFrame(
3758-
buttonKey: buttonKey,
3759-
mediaSize: const Size(800, 600),
3760-
itemHeight: 100.0,
3761-
isExpanded: true,
3752+
await tester.pumpWidget(buildDropdownWithHint(
37623753
alignment: AlignmentDirectional.bottomStart,
3763-
hint: const Text(hintText)),
3764-
);
3754+
isExpanded: true,
3755+
));
37653756
expect(tester.getBottomLeft(find.text(hintText)).dx, 0.0);
37663757
expect(tester.getBottomLeft(find.text(hintText)).dy, 350.0);
37673758
// AlignmentDirectional.center
3768-
await tester.pumpWidget(buildFrame(
3769-
buttonKey: buttonKey,
3770-
mediaSize: const Size(800, 600),
3771-
itemHeight: 100.0,
3759+
await tester.pumpWidget(buildDropdownWithHint(
3760+
alignment: AlignmentDirectional.center,
37723761
isExpanded: true,
3762+
));
3763+
expect(tester.getCenter(find.text(hintText)).dx, 388.0);
3764+
expect(tester.getCenter(find.text(hintText)).dy, 300.0);
3765+
// AlignmentDirectional.topEnd
3766+
await tester.pumpWidget(buildDropdownWithHint(
3767+
alignment: AlignmentDirectional.topEnd,
3768+
isExpanded: true,
3769+
));
3770+
expect(tester.getTopRight(find.text(hintText)).dx, 776.0);
3771+
expect(tester.getTopRight(find.text(hintText)).dy, 250.0);
3772+
// AlignmentDirectional.centerEnd
3773+
await tester.pumpWidget(buildDropdownWithHint(
3774+
alignment: AlignmentDirectional.centerEnd,
3775+
isExpanded: true,
3776+
));
3777+
expect(tester.getTopRight(find.text(hintText)).dx, 776.0);
3778+
expect(tester.getTopRight(find.text(hintText)).dy, 292.0);
3779+
// AlignmentDirectional.bottomEnd
3780+
await tester.pumpWidget(buildDropdownWithHint(
3781+
alignment: AlignmentDirectional.bottomEnd,
3782+
isExpanded: true,
3783+
));
3784+
expect(tester.getBottomRight(find.text(hintText)).dx, 776.0);
3785+
expect(tester.getBottomRight(find.text(hintText)).dy, 350.0);
3786+
});
3787+
3788+
testWidgets('DropdownButton hint alignment with selectedItemBuilder', (WidgetTester tester) async {
3789+
const String hintText = 'hint';
3790+
3791+
// AlignmentDirectional.centerStart (default)
3792+
await tester.pumpWidget(buildDropdownWithHint(
3793+
alignment: AlignmentDirectional.centerStart,
3794+
isExpanded: false,
3795+
enableSelectedItemBuilder: true,
3796+
));
3797+
expect(tester.getTopLeft(find.text(hintText)).dx, 348.0);
3798+
expect(tester.getTopLeft(find.text(hintText)).dy, 292.0);
3799+
// AlignmentDirectional.topStart
3800+
await tester.pumpWidget(buildDropdownWithHint(
3801+
alignment: AlignmentDirectional.topStart,
3802+
isExpanded: false,
3803+
enableSelectedItemBuilder: true,
3804+
));
3805+
expect(tester.getTopLeft(find.text(hintText)).dx, 348.0);
3806+
expect(tester.getTopLeft(find.text(hintText)).dy, 250.0);
3807+
// AlignmentDirectional.bottomStart
3808+
await tester.pumpWidget(buildDropdownWithHint(
3809+
alignment: AlignmentDirectional.bottomStart,
3810+
isExpanded: false,
3811+
enableSelectedItemBuilder: true,
3812+
));
3813+
expect(tester.getBottomLeft(find.text(hintText)).dx, 348.0);
3814+
expect(tester.getBottomLeft(find.text(hintText)).dy, 350.0);
3815+
// AlignmentDirectional.center
3816+
await tester.pumpWidget(buildDropdownWithHint(
37733817
alignment: AlignmentDirectional.center,
3774-
hint: const Text(hintText)),
3775-
);
3818+
isExpanded: false,
3819+
enableSelectedItemBuilder: true,
3820+
));
37763821
expect(tester.getCenter(find.text(hintText)).dx, 388.0);
37773822
expect(tester.getCenter(find.text(hintText)).dy, 300.0);
37783823
// AlignmentDirectional.topEnd
3779-
await tester.pumpWidget(buildFrame(
3780-
buttonKey: buttonKey,
3781-
mediaSize: const Size(800, 600),
3782-
itemHeight: 100.0,
3824+
await tester.pumpWidget(buildDropdownWithHint(
3825+
alignment: AlignmentDirectional.topEnd,
3826+
isExpanded: false,
3827+
enableSelectedItemBuilder: true,
3828+
));
3829+
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
3830+
expect(tester.getTopRight(find.text(hintText)).dy, 250.0);
3831+
// AlignmentDirectional.centerEnd
3832+
await tester.pumpWidget(buildDropdownWithHint(
3833+
alignment: AlignmentDirectional.centerEnd,
3834+
isExpanded: false,
3835+
enableSelectedItemBuilder: true,
3836+
));
3837+
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
3838+
expect(tester.getTopRight(find.text(hintText)).dy, 292.0);
3839+
// AlignmentDirectional.bottomEnd
3840+
await tester.pumpWidget(buildDropdownWithHint(
3841+
alignment: AlignmentDirectional.bottomEnd,
3842+
isExpanded: false,
3843+
enableSelectedItemBuilder: true,
3844+
));
3845+
expect(tester.getTopRight(find.text(hintText)).dx, 428.0);
3846+
expect(tester.getTopRight(find.text(hintText)).dy, 334.0);
3847+
3848+
// DropdownButton with `isExpanded: true`
3849+
// AlignmentDirectional.centerStart (default)
3850+
await tester.pumpWidget(buildDropdownWithHint(
3851+
alignment: AlignmentDirectional.centerStart,
3852+
isExpanded: true,
3853+
enableSelectedItemBuilder: true,
3854+
));
3855+
expect(tester.getTopLeft(find.text(hintText)).dx, 0.0);
3856+
expect(tester.getTopLeft(find.text(hintText)).dy, 292.0);
3857+
// AlignmentDirectional.topStart
3858+
await tester.pumpWidget(buildDropdownWithHint(
3859+
alignment: AlignmentDirectional.topStart,
3860+
isExpanded: true,
3861+
enableSelectedItemBuilder: true,
3862+
));
3863+
expect(tester.getTopLeft(find.text(hintText)).dx, 0.0);
3864+
expect(tester.getTopLeft(find.text(hintText)).dy, 250.0);
3865+
// AlignmentDirectional.bottomStart
3866+
await tester.pumpWidget(buildDropdownWithHint(
3867+
alignment: AlignmentDirectional.bottomStart,
3868+
isExpanded: true,
3869+
enableSelectedItemBuilder: true,
3870+
));
3871+
expect(tester.getBottomLeft(find.text(hintText)).dx, 0.0);
3872+
expect(tester.getBottomLeft(find.text(hintText)).dy, 350.0);
3873+
// AlignmentDirectional.center
3874+
await tester.pumpWidget(buildDropdownWithHint(
3875+
alignment: AlignmentDirectional.center,
37833876
isExpanded: true,
3877+
enableSelectedItemBuilder: true,
3878+
));
3879+
expect(tester.getCenter(find.text(hintText)).dx, 388.0);
3880+
expect(tester.getCenter(find.text(hintText)).dy, 300.0);
3881+
// AlignmentDirectional.topEnd
3882+
await tester.pumpWidget(buildDropdownWithHint(
37843883
alignment: AlignmentDirectional.topEnd,
3785-
hint: const Text(hintText)),
3786-
);
3884+
isExpanded: true,
3885+
enableSelectedItemBuilder: true,
3886+
));
37873887
expect(tester.getTopRight(find.text(hintText)).dx, 776.0);
37883888
expect(tester.getTopRight(find.text(hintText)).dy, 250.0);
37893889
// AlignmentDirectional.centerEnd
3790-
await tester.pumpWidget(buildFrame(
3791-
buttonKey: buttonKey,
3792-
mediaSize: const Size(800, 600),
3793-
itemHeight: 100.0,
3794-
isExpanded: true,
3890+
await tester.pumpWidget(buildDropdownWithHint(
37953891
alignment: AlignmentDirectional.centerEnd,
3796-
hint: const Text(hintText)),
3797-
);
3892+
isExpanded: true,
3893+
enableSelectedItemBuilder: true,
3894+
));
37983895
expect(tester.getTopRight(find.text(hintText)).dx, 776.0);
37993896
expect(tester.getTopRight(find.text(hintText)).dy, 292.0);
38003897
// AlignmentDirectional.bottomEnd
3801-
await tester.pumpWidget(buildFrame(
3802-
buttonKey: buttonKey,
3803-
mediaSize: const Size(800, 600),
3804-
itemHeight: 100.0,
3805-
isExpanded: true,
3898+
await tester.pumpWidget(buildDropdownWithHint(
38063899
alignment: AlignmentDirectional.bottomEnd,
3807-
hint: const Text(hintText)),
3808-
);
3900+
isExpanded: true,
3901+
enableSelectedItemBuilder: true,
3902+
));
38093903
expect(tester.getBottomRight(find.text(hintText)).dx, 776.0);
38103904
expect(tester.getBottomRight(find.text(hintText)).dy, 350.0);
38113905
});

0 commit comments

Comments
 (0)