Unverified Commit 336d60d2 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Updated DropdownMenu example and added a test (#133592)

parent 1e770c38
...@@ -321,7 +321,6 @@ final Set<String> _knownMissingTests = <String>{ ...@@ -321,7 +321,6 @@ final Set<String> _knownMissingTests = <String>{
'examples/api/test/material/scrollbar/scrollbar.1_test.dart', 'examples/api/test/material/scrollbar/scrollbar.1_test.dart',
'examples/api/test/material/scrollbar/scrollbar.0_test.dart', 'examples/api/test/material/scrollbar/scrollbar.0_test.dart',
'examples/api/test/material/dropdown_menu/dropdown_menu.1_test.dart', 'examples/api/test/material/dropdown_menu/dropdown_menu.1_test.dart',
'examples/api/test/material/dropdown_menu/dropdown_menu.0_test.dart',
'examples/api/test/material/radio/radio.toggleable.0_test.dart', 'examples/api/test/material/radio/radio.toggleable.0_test.dart',
'examples/api/test/material/radio/radio.0_test.dart', 'examples/api/test/material/radio/radio.0_test.dart',
'examples/api/test/material/search_anchor/search_anchor.0_test.dart', 'examples/api/test/material/search_anchor/search_anchor.0_test.dart',
......
...@@ -2,13 +2,45 @@ ...@@ -2,13 +2,45 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// which is the default configuration, and the second one has a filled input decoration.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Flutter code sample for [DropdownMenu]s. The first dropdown menu has an outlined border. // Flutter code sample for [DropdownMenu]s. The first dropdown menu
// has the default outlined border and demos using the
// [DropdownMenuEntry] style parameter to customize its appearance.
// The second dropdown menu customizes the appearance of the dropdown
// menu's text field with its [InputDecorationTheme] parameter.
void main() {
runApp(const DropdownMenuExample());
}
// DropdownMenuEntry labels and values for the first dropdown menu.
enum ColorLabel {
blue('Blue', Colors.blue),
pink('Pink', Colors.pink),
green('Green', Colors.green),
yellow('Orange', Colors.orange),
grey('Grey', Colors.grey);
const ColorLabel(this.label, this.color);
final String label;
final Color color;
}
// DropdownMenuEntry labels and values for the second dropdown menu.
enum IconLabel {
smile('Smile', Icons.sentiment_satisfied_outlined),
cloud(
'Cloud',
Icons.cloud_outlined,
),
brush('Brush', Icons.brush_outlined),
heart('Heart', Icons.favorite);
void main() => runApp(const DropdownMenuExample()); const IconLabel(this.label, this.icon);
final String label;
final IconData icon;
}
class DropdownMenuExample extends StatefulWidget { class DropdownMenuExample extends StatefulWidget {
const DropdownMenuExample({super.key}); const DropdownMenuExample({super.key});
...@@ -25,18 +57,6 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> { ...@@ -25,18 +57,6 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<DropdownMenuEntry<ColorLabel>> colorEntries = <DropdownMenuEntry<ColorLabel>>[];
for (final ColorLabel color in ColorLabel.values) {
colorEntries.add(
DropdownMenuEntry<ColorLabel>(value: color, label: color.label, enabled: color.label != 'Grey'),
);
}
final List<DropdownMenuEntry<IconLabel>> iconEntries = <DropdownMenuEntry<IconLabel>>[];
for (final IconLabel icon in IconLabel.values) {
iconEntries.add(DropdownMenuEntry<IconLabel>(value: icon, label: icon.label));
}
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,
...@@ -55,20 +75,30 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> { ...@@ -55,20 +75,30 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> {
initialSelection: ColorLabel.green, initialSelection: ColorLabel.green,
controller: colorController, controller: colorController,
label: const Text('Color'), label: const Text('Color'),
dropdownMenuEntries: colorEntries,
onSelected: (ColorLabel? color) { onSelected: (ColorLabel? color) {
setState(() { setState(() {
selectedColor = color; selectedColor = color;
}); });
}, },
dropdownMenuEntries: ColorLabel.values.map<DropdownMenuEntry<ColorLabel>>(
(ColorLabel color) {
return DropdownMenuEntry<ColorLabel>(
value: color,
label: color.label,
enabled: color.label != 'Grey',
style: MenuItemButton.styleFrom(
foregroundColor: color.color,
),
);
}
).toList(),
), ),
const SizedBox(width: 20), const SizedBox(width: 24),
DropdownMenu<IconLabel>( DropdownMenu<IconLabel>(
controller: iconController, controller: iconController,
enableFilter: true, enableFilter: true,
leadingIcon: const Icon(Icons.search), leadingIcon: const Icon(Icons.search),
label: const Text('Icon'), label: const Text('Icon'),
dropdownMenuEntries: iconEntries,
inputDecorationTheme: const InputDecorationTheme( inputDecorationTheme: const InputDecorationTheme(
filled: true, filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 5.0), contentPadding: EdgeInsets.symmetric(vertical: 5.0),
...@@ -78,7 +108,16 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> { ...@@ -78,7 +108,16 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> {
selectedIcon = icon; selectedIcon = icon;
}); });
}, },
) dropdownMenuEntries: IconLabel.values.map<DropdownMenuEntry<IconLabel>>(
(IconLabel icon) {
return DropdownMenuEntry<IconLabel>(
value: icon,
label: icon.label,
leadingIcon: Icon(icon.icon),
);
},
).toList(),
),
], ],
), ),
), ),
...@@ -105,29 +144,3 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> { ...@@ -105,29 +144,3 @@ class _DropdownMenuExampleState extends State<DropdownMenuExample> {
); );
} }
} }
enum ColorLabel {
blue('Blue', Colors.blue),
pink('Pink', Colors.pink),
green('Green', Colors.green),
yellow('Yellow', Colors.yellow),
grey('Grey', Colors.grey);
const ColorLabel(this.label, this.color);
final String label;
final Color color;
}
enum IconLabel {
smile('Smile', Icons.sentiment_satisfied_outlined),
cloud(
'Cloud',
Icons.cloud_outlined,
),
brush('Brush', Icons.brush_outlined),
heart('Heart', Icons.favorite);
const IconLabel(this.label, this.icon);
final String label;
final IconData icon;
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/dropdown_menu/dropdown_menu.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('DropdownMenu', (WidgetTester tester) async {
await tester.pumpWidget(
const example.DropdownMenuExample(),
);
expect(find.text('You selected a Blue Smile'), findsNothing);
final Finder colorMenu = find.byType(DropdownMenu<example.ColorLabel>);
final Finder iconMenu = find.byType(DropdownMenu<example.IconLabel>);
expect(colorMenu, findsOneWidget);
expect(iconMenu, findsOneWidget);
Finder findMenuItem(String label) {
return find.widgetWithText(MenuItemButton, label).last;
}
await tester.tap(colorMenu);
await tester.pumpAndSettle();
expect(findMenuItem('Blue'), findsOneWidget);
expect(findMenuItem('Pink'), findsOneWidget);
expect(findMenuItem('Green'), findsOneWidget);
expect(findMenuItem('Orange'), findsOneWidget);
expect(findMenuItem('Grey'), findsOneWidget);
await tester.tap(findMenuItem('Blue'));
// The DropdownMenu's onSelected callback is delayed
// with SchedulerBinding.instance.addPostFrameCallback
// to give the focus a chance to return to where it was
// before the menu appeared. The pumpAndSettle()
// give the callback a chance to run.
await tester.pumpAndSettle();
await tester.tap(iconMenu);
await tester.pumpAndSettle();
expect(findMenuItem('Smile'), findsOneWidget);
expect(findMenuItem('Cloud'), findsOneWidget);
expect(findMenuItem('Brush'), findsOneWidget);
expect(findMenuItem('Heart'), findsOneWidget);
await tester.tap(findMenuItem('Smile'));
await tester.pumpAndSettle();
expect(find.text('You selected a Blue Smile'), findsOneWidget);
});
}
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