Fix DropdownMenu menu is detached from the text field (#159665)
## Description This PR fixes `DropdownMenu` menu vertical position when tight constraints are given to the `DropdownMenu`. Before:  After:  ## Related Issue Fixes [DropdownMenu does not correctly handle incoming maxWidth and minHeight constraints](https://github.com/flutter/flutter/issues/147076). (It fixes the minHeight part, the maxWidth part was already fixed in https://github.com/flutter/flutter/pull/147233). ## Tests Adds 4 tests.
This commit is contained in:
parent
f66f6a7cb9
commit
11fa41e699
@ -1022,6 +1022,17 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
);
|
||||
}
|
||||
|
||||
// Wrap the menu anchor with an Align to narrow down the constraints.
|
||||
// Without this Align, when tight constraints are applied to DropdownMenu,
|
||||
// the menu will appear below these constraints instead of below the
|
||||
// text field.
|
||||
menuAnchor = Align(
|
||||
alignment: AlignmentDirectional.topStart,
|
||||
widthFactor: 1.0,
|
||||
heightFactor: 1.0,
|
||||
child: menuAnchor,
|
||||
);
|
||||
|
||||
return Actions(
|
||||
actions: <Type, Action<Intent>>{
|
||||
_ArrowUpIntent: CallbackAction<_ArrowUpIntent>(
|
||||
|
@ -3488,6 +3488,94 @@ void main() {
|
||||
// None of the menus should be closed.
|
||||
expect(dropdownMenuAnchor.controller!.isOpen, true);
|
||||
});
|
||||
|
||||
group('The menu is attached at the bottom of the TextField', () {
|
||||
// Define the expected text field bottom instead of querying it using
|
||||
// tester.getRect because when tight constraints are applied to the
|
||||
// Dropdown the TextField bounds are expanded while the visible size
|
||||
// remains 56 pixels.
|
||||
const double textFieldBottom = 56.0;
|
||||
|
||||
testWidgets('when given loose constraints and expandedInsets is set', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: DropdownMenu<TestMenu>(
|
||||
expandedInsets: EdgeInsets.zero,
|
||||
initialSelection: TestMenu.mainMenu3,
|
||||
dropdownMenuEntries: menuChildrenWithIcons,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the menu.
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getRect(findMenuMaterial()).top, textFieldBottom);
|
||||
});
|
||||
|
||||
testWidgets('when given tight constraints and expandedInsets is set', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SizedBox(
|
||||
width: 200,
|
||||
height: 300,
|
||||
child: DropdownMenu<TestMenu>(
|
||||
expandedInsets: EdgeInsets.zero,
|
||||
initialSelection: TestMenu.mainMenu3,
|
||||
dropdownMenuEntries: menuChildrenWithIcons,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the menu.
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getRect(findMenuMaterial()).top, textFieldBottom);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/147076.
|
||||
testWidgets('when given loose constraints and expandedInsets is not set', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: DropdownMenu<TestMenu>(
|
||||
initialSelection: TestMenu.mainMenu3,
|
||||
dropdownMenuEntries: menuChildrenWithIcons,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the menu.
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getRect(findMenuMaterial()).top, textFieldBottom);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/147076.
|
||||
testWidgets('when given tight constraints and expandedInsets is not set', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SizedBox(
|
||||
width: 200,
|
||||
height: 300,
|
||||
child: DropdownMenu<TestMenu>(
|
||||
initialSelection: TestMenu.mainMenu3,
|
||||
dropdownMenuEntries: menuChildrenWithIcons,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the menu.
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getRect(findMenuMaterial()).top, textFieldBottom);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
enum TestMenu {
|
||||
|
Loading…
x
Reference in New Issue
Block a user