Unverified Commit 85e5b210 authored by Shi-Hao Hong's avatar Shi-Hao Hong Committed by GitHub

Implement DropdownMenuItem.onTap (#53368)

* Implement DropdownMenuItem.onTap
parent c7a6e300
......@@ -145,9 +145,15 @@ class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>>
}
void _handleOnTap() {
final DropdownMenuItem<T> dropdownMenuItem = widget.route.items[widget.itemIndex].item;
if (dropdownMenuItem.onTap != null) {
dropdownMenuItem.onTap();
}
Navigator.pop(
context,
_DropdownRouteResult<T>(widget.route.items[widget.itemIndex].item.value),
_DropdownRouteResult<T>(dropdownMenuItem.value),
);
}
......@@ -656,11 +662,15 @@ class DropdownMenuItem<T> extends _DropdownMenuItemContainer {
/// The [child] argument is required.
const DropdownMenuItem({
Key key,
this.onTap,
this.value,
@required Widget child,
}) : assert(child != null),
super(key: key, child: child);
/// Called when the dropdown menu item is tapped.
final VoidCallback onTap;
/// The value to return if the user selects this menu item.
///
/// Eventually returned in a call to [DropdownButton.onChanged].
......
......@@ -2361,4 +2361,89 @@ void main() {
expect(value, equals('two'));
expect(dropdownButtonTapCounter, 2); // Should not change.
});
testWidgets('DropdownMenuItem onTap callback is called when defined', (WidgetTester tester) async {
String value = 'one';
final List<int> menuItemTapCounters = <int>[0, 0, 0, 0];
void onChanged(String newValue) { value = newValue; }
final List<VoidCallback> onTapCallbacks = <VoidCallback>[
() { menuItemTapCounters[0] += 1; },
() { menuItemTapCounters[1] += 1; },
() { menuItemTapCounters[2] += 1; },
() { menuItemTapCounters[3] += 1; },
];
int currentIndex = -1;
await tester.pumpWidget(
TestApp(
textDirection: TextDirection.ltr,
child: Material(
child: RepaintBoundary(
child: DropdownButton<String>(
value: value,
onChanged: onChanged,
items: menuItems.map<DropdownMenuItem<String>>((String item) {
currentIndex += 1;
return DropdownMenuItem<String>(
value: item,
onTap: onTapCallbacks[currentIndex],
child: Text(item),
);
}).toList(),
),
),
),
),
);
// Tap dropdown button.
await tester.tap(find.text('one'));
await tester.pumpAndSettle();
expect(value, equals('one'));
// Counters should still be zero.
expect(menuItemTapCounters, <int>[0, 0, 0, 0]);
// Tap dropdown menu item.
await tester.tap(find.text('three').last);
await tester.pumpAndSettle();
// Should update the counter for the third item (second index).
expect(value, equals('three'));
expect(menuItemTapCounters, <int>[0, 0, 1, 0]);
// Tap dropdown button again.
await tester.tap(find.text('three'));
await tester.pumpAndSettle();
// Should not change.
expect(value, equals('three'));
expect(menuItemTapCounters, <int>[0, 0, 1, 0]);
// Tap dropdown menu item.
await tester.tap(find.text('two').last);
await tester.pumpAndSettle();
// Should update the counter for the second item (first index).
expect(value, equals('two'));
expect(menuItemTapCounters, <int>[0, 1, 1, 0]);
// Tap dropdown button again.
await tester.tap(find.text('two'));
await tester.pumpAndSettle();
// Should not change.
expect(value, equals('two'));
expect(menuItemTapCounters, <int>[0, 1, 1, 0]);
// Tap the already selected menu item
await tester.tap(find.text('two').last);
await tester.pumpAndSettle();
// Should update the counter for the second item (first index), even
// though it was already selected.
expect(value, equals('two'));
expect(menuItemTapCounters, <int>[0, 2, 1, 0]);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment