mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix DropdownMenu focus traversal (#153931)
## Description This PR fixes `DropdownMenu` focus traversal. Before this PR, if a `DropdownMenu` contains several items, the 'tab' key had to be pressed many times before the focus move to the inner text field. This fix is based on https://github.com/flutter/flutter/issues/131120#issuecomment-1654233358. ## Related Issue Fixes https://github.com/flutter/flutter/issues/131120. ## Tests Adds 1 test.
This commit is contained in:
parent
b6c14d783a
commit
402ed6c503
@ -670,7 +670,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
)
|
||||
: effectiveStyle;
|
||||
|
||||
final Widget menuItemButton = MenuItemButton(
|
||||
final Widget menuItemButton = MenuItemButton(
|
||||
key: enableScrollToHighlight ? buttonItemKeys[i] : null,
|
||||
style: effectiveStyle,
|
||||
leadingIcon: entry.leadingIcon,
|
||||
@ -890,7 +890,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
width: widget.width,
|
||||
children: <Widget>[
|
||||
textField,
|
||||
..._initialMenu!,
|
||||
..._initialMenu!.map((Widget item) => ExcludeFocus(excluding: !controller.isOpen, child: item)),
|
||||
trailingButton,
|
||||
leadingButton,
|
||||
],
|
||||
|
@ -2427,6 +2427,44 @@ void main() {
|
||||
expect(box, paints..rrect(color: theme.colorScheme.primary));
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/131120.
|
||||
testWidgets('Focus traversal ignores non visible entries', (WidgetTester tester) async {
|
||||
final FocusNode buttonFocusNode = FocusNode();
|
||||
addTearDown(buttonFocusNode.dispose);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
DropdownMenu<TestMenu>(dropdownMenuEntries: menuChildren),
|
||||
ElevatedButton(
|
||||
focusNode: buttonFocusNode,
|
||||
onPressed: () {},
|
||||
child: const Text('Button'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Move the focus to the text field.
|
||||
primaryFocus!.nextFocus();
|
||||
await tester.pump();
|
||||
final Element textField = tester.element(find.byType(TextField));
|
||||
expect(Focus.of(textField).hasFocus, isTrue);
|
||||
|
||||
// Move the focus to the dropdown trailing icon.
|
||||
primaryFocus!.nextFocus();
|
||||
await tester.pump();
|
||||
final Element iconButton = tester.firstElement(find.byIcon(Icons.arrow_drop_down));
|
||||
expect(Focus.of(iconButton).hasFocus, isTrue);
|
||||
|
||||
// Move the focus to the elevated button.
|
||||
primaryFocus!.nextFocus();
|
||||
await tester.pump();
|
||||
expect(buttonFocusNode.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('DropdownMenu honors inputFormatters', (WidgetTester tester) async {
|
||||
int called = 0;
|
||||
final TextInputFormatter formatter = TextInputFormatter.withFunction(
|
||||
@ -2562,7 +2600,7 @@ void main() {
|
||||
DropdownMenu<int>(
|
||||
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
||||
),
|
||||
DropdownMenu<int>(
|
||||
DropdownMenu<int>(
|
||||
textAlign: TextAlign.center,
|
||||
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user