Skip to content

Commit 59400bf

Browse files
authored
Request focus in onTap callback from DropdownButton (flutter#93716)
1 parent 03861e5 commit 59400bf

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

packages/flutter/lib/src/material/dropdown.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
12761276
borderRadius: widget.borderRadius,
12771277
);
12781278

1279+
focusNode?.requestFocus();
12791280
navigator.push(_dropdownRoute!).then<void>((_DropdownRouteResult<T>? newValue) {
12801281
_removeDropdownRoute();
12811282
if (!mounted || newValue == null)

packages/flutter/test/material/dropdown_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,6 +2775,54 @@ void main() {
27752775
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last)).hasPrimaryFocus, isFalse);
27762776
});
27772777

2778+
testWidgets('DropdownButton onTap callback can request focus', (WidgetTester tester) async {
2779+
final FocusNode focusNode = FocusNode(debugLabel: 'DropdownButton')..addListener(() { });
2780+
int? value = 1;
2781+
final List<int> hugeMenuItems = List<int>.generate(100, (int index) => index);
2782+
2783+
await tester.pumpWidget(
2784+
MaterialApp(
2785+
home: Scaffold(
2786+
body: Center(
2787+
child: StatefulBuilder(
2788+
builder: (BuildContext context, StateSetter setState) {
2789+
return DropdownButton<int>(
2790+
focusNode: focusNode,
2791+
onChanged: (int? newValue) {
2792+
setState(() {
2793+
value = newValue;
2794+
});
2795+
},
2796+
value: value,
2797+
itemHeight: null,
2798+
items: hugeMenuItems.map<DropdownMenuItem<int>>((int item) {
2799+
return DropdownMenuItem<int>(
2800+
key: ValueKey<int>(item),
2801+
value: item,
2802+
child: Text(item.toString()),
2803+
);
2804+
}).toList(),
2805+
);
2806+
},
2807+
),
2808+
),
2809+
),
2810+
),
2811+
);
2812+
2813+
await tester.pump(); // Pump a frame for autofocus to take effect.
2814+
expect(focusNode.hasPrimaryFocus, isFalse);
2815+
2816+
await tester.tap(find.text('1'));
2817+
await tester.pumpAndSettle();
2818+
2819+
// Close the dropdown menu.
2820+
await tester.tapAt(const Offset(1.0, 1.0));
2821+
await tester.pumpAndSettle();
2822+
2823+
expect(focusNode.hasPrimaryFocus, isTrue);
2824+
});
2825+
27782826
testWidgets('DropdownButton changes selected item with arrow keys', (WidgetTester tester) async {
27792827
final FocusNode focusNode = FocusNode(debugLabel: 'DropdownButton');
27802828
String? value = 'one';

0 commit comments

Comments
 (0)