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;
|
: effectiveStyle;
|
||||||
|
|
||||||
final Widget menuItemButton = MenuItemButton(
|
final Widget menuItemButton = MenuItemButton(
|
||||||
key: enableScrollToHighlight ? buttonItemKeys[i] : null,
|
key: enableScrollToHighlight ? buttonItemKeys[i] : null,
|
||||||
style: effectiveStyle,
|
style: effectiveStyle,
|
||||||
leadingIcon: entry.leadingIcon,
|
leadingIcon: entry.leadingIcon,
|
||||||
@ -890,7 +890,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
|||||||
width: widget.width,
|
width: widget.width,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
textField,
|
textField,
|
||||||
..._initialMenu!,
|
..._initialMenu!.map((Widget item) => ExcludeFocus(excluding: !controller.isOpen, child: item)),
|
||||||
trailingButton,
|
trailingButton,
|
||||||
leadingButton,
|
leadingButton,
|
||||||
],
|
],
|
||||||
|
@ -2427,6 +2427,44 @@ void main() {
|
|||||||
expect(box, paints..rrect(color: theme.colorScheme.primary));
|
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 {
|
testWidgets('DropdownMenu honors inputFormatters', (WidgetTester tester) async {
|
||||||
int called = 0;
|
int called = 0;
|
||||||
final TextInputFormatter formatter = TextInputFormatter.withFunction(
|
final TextInputFormatter formatter = TextInputFormatter.withFunction(
|
||||||
@ -2562,7 +2600,7 @@ void main() {
|
|||||||
DropdownMenu<int>(
|
DropdownMenu<int>(
|
||||||
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
||||||
),
|
),
|
||||||
DropdownMenu<int>(
|
DropdownMenu<int>(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
dropdownMenuEntries: <DropdownMenuEntry<int>>[],
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user