feat: Add alignmentOffset to DropdownMenu (#151731)

Changes:
- Introduced `alignmentOffset` property to `DropdownMenu` to allow adjustment of menu alignment.
- Updated the `MenuAnchor` widget to utilize the new `alignmentOffset` property.
- Default value for `alignmentOffset` is `Offset.zero`, meaning no additional spacing by default.

Motivation: 
- This PR closes #151524 
- @nate-thegrate, please let me know if I need to make changes in order for this PR to be merged

The motivation behind this change is to provide developers with more control over the spacing between the `MenuAnchor` and `dropdownMenuEntries` in the `DropdownMenu` widget. This enhancement allows for better alignment and customization of the dropdown menu appearance.
| before | after |
| :---: | :---: |
| <img width="372" alt="Screenshot 2024-07-14 at 8 03 14 PM" src="https://github.com/user-attachments/assets/4a45b843-7fa4-44fd-843c-c7209c6f57ae">      |      <img width="364" alt="Screenshot 2024-07-14 at 8 03 27 PM" src="https://github.com/user-attachments/assets/12e8b857-aefb-4aaf-a310-4a002abcbc2f">   |

Initially, it was suggested to use a `SizedBox` to introduce spacing. However, upon further examination of the source code, it was discovered that the `DropdownMenuEntries` are rendered on the screen via an `OverlayPortal`. This necessitated leveraging the existing `alignmentOffset` property within the `MenuAnchor` for a more seamless and effective alignment adjustment.
This commit is contained in:
Byeongjin Kang 2024-07-25 06:17:06 +09:00 committed by GitHub
parent f060312115
commit 6fdcb0a511
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 0 deletions

View File

@ -175,6 +175,7 @@ class DropdownMenu<T> extends StatefulWidget {
this.expandedInsets,
this.filterCallback,
this.searchCallback,
this.alignmentOffset,
required this.dropdownMenuEntries,
this.inputFormatters,
}) : assert(filterCallback == null || enableFilter);
@ -475,6 +476,9 @@ class DropdownMenu<T> extends StatefulWidget {
/// and notifies its listeners on [TextEditingValue] changes.
final List<TextInputFormatter>? inputFormatters;
/// {@macro flutter.material.MenuAnchor.alignmentOffset}
final Offset? alignmentOffset;
@override
State<DropdownMenu<T>> createState() => _DropdownMenuState<T>();
}
@ -784,6 +788,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
Widget menuAnchor = MenuAnchor(
style: effectiveMenuStyle,
alignmentOffset: widget.alignmentOffset,
controller: _controller,
menuChildren: menu,
crossAxisUnconstrained: false,

View File

@ -181,6 +181,7 @@ class MenuAnchor extends StatefulWidget {
/// Defaults to the ambient [MenuThemeData.style].
final MenuStyle? style;
/// {@template flutter.material.MenuAnchor.alignmentOffset}
/// The offset of the menu relative to the alignment origin determined by
/// [MenuStyle.alignment] on the [style] attribute and the ambient
/// [Directionality].
@ -201,6 +202,7 @@ class MenuAnchor extends StatefulWidget {
/// [alignmentOffset] move the menu position to the left.
///
/// Defaults to [Offset.zero].
/// {@endtemplate}
final Offset? alignmentOffset;
/// {@macro flutter.material.Material.clipBehavior}

View File

@ -2432,6 +2432,28 @@ void main() {
final TextField textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.text);
});
testWidgets('DropdownMenu passes an alignmentOffset to MenuAnchor', (WidgetTester tester) async {
const Offset alignmentOffset = Offset(0, 16);
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: DropdownMenu<String>(
alignmentOffset: alignmentOffset,
dropdownMenuEntries: <DropdownMenuEntry<String>>[
DropdownMenuEntry<String>(value: '1', label: 'One'),
DropdownMenuEntry<String>(value: '2', label: 'Two'),
],
),
),
),
);
final MenuAnchor menuAnchor = tester.widget<MenuAnchor>(find.byType(MenuAnchor));
expect(menuAnchor.alignmentOffset, alignmentOffset);
});
}
enum TestMenu {