fix DropdownMenu
crashes when provided menuStyle with small maximumSize (#162380)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> fix #162356 Previously `DropdownMenu` overwrites `minimumSize` in `menuStyle` to be the width of the `TextField` Now it set the `minimumSize` to be the min between the width of the `TextField` and the width of `maximumSize`, so that the menu can be smaller than the `TextField`. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
1624890a8d
commit
4aafcce483
@ -967,11 +967,19 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
final double? anchorWidth = getWidth(_anchorKey);
|
||||
if (widget.width != null) {
|
||||
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
||||
minimumSize: MaterialStatePropertyAll<Size?>(Size(widget.width!, 0.0)),
|
||||
minimumSize: MaterialStateProperty.resolveWith<Size?>((Set<MaterialState> states) {
|
||||
final double? effectiveMaximumWidth =
|
||||
effectiveMenuStyle!.maximumSize?.resolve(states)?.width;
|
||||
return Size(math.min(widget.width!, effectiveMaximumWidth ?? 0.0), 0.0);
|
||||
}),
|
||||
);
|
||||
} else if (anchorWidth != null) {
|
||||
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
||||
minimumSize: MaterialStatePropertyAll<Size?>(Size(anchorWidth, 0.0)),
|
||||
minimumSize: MaterialStateProperty.resolveWith<Size?>((Set<MaterialState> states) {
|
||||
final double? effectiveMaximumWidth =
|
||||
effectiveMenuStyle!.maximumSize?.resolve(states)?.width;
|
||||
return Size(math.min(anchorWidth, effectiveMaximumWidth ?? 0.0), 0.0);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3952,6 +3952,52 @@ void main() {
|
||||
textField = tester.widget(find.byType(TextField));
|
||||
expect(textField.textInputAction, TextInputAction.next);
|
||||
});
|
||||
|
||||
testWidgets('items can be constrainted to be smaller than the text field with menuStyle', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
const String longLabel = 'This is a long text that it can overflow.';
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: DropdownMenu<int>(
|
||||
dropdownMenuEntries: <DropdownMenuEntry<int>>[
|
||||
DropdownMenuEntry<int>(value: 0, label: longLabel),
|
||||
],
|
||||
menuStyle: MenuStyle(maximumSize: WidgetStatePropertyAll<Size>(Size(150.0, 50.0))),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
expect(tester.getSize(findMenuItemButton(longLabel)).width, 150.0);
|
||||
|
||||
// The overwrite of menuStyle is different when a width is provided,
|
||||
// So it needs to be tested separately.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: DropdownMenu<TestMenu>(
|
||||
width: 200.0,
|
||||
dropdownMenuEntries: menuChildren,
|
||||
menuStyle: const MenuStyle(
|
||||
maximumSize: WidgetStatePropertyAll<Size>(Size(150.0, 50.0)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
expect(tester.getSize(findMenuItemButton(menuChildren.first.label)).width, 150.0);
|
||||
});
|
||||
}
|
||||
|
||||
enum TestMenu {
|
||||
|
Loading…
x
Reference in New Issue
Block a user