Skip to content

Commit 0e7295f

Browse files
authored
Add a simplified SimpleCascadingMenuApp example (#149147)
The current MenuAnchor example in the API Docs is comprehensive and complicated for beginners. I have added a simple bare bone example without shortcuts, enums, etc in examples/api/lib/material/menu_anchor/ as `menu_anchor.3.dart`. The example is contributed by @mafreud Fixes flutter/flutter#148104
1 parent 8e15e56 commit 0e7295f

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
7+
/// Flutter code sample for [SimpleCascadingMenuApp].
8+
9+
void main() => runApp(const SimpleCascadingMenuApp());
10+
11+
/// A Simple Cascading Menu example using the [MenuAnchor] Widget.
12+
class MyCascadingMenu extends StatefulWidget {
13+
const MyCascadingMenu({super.key});
14+
15+
@override
16+
State<MyCascadingMenu> createState() => _MyCascadingMenuState();
17+
}
18+
19+
class _MyCascadingMenuState extends State<MyCascadingMenu> {
20+
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');
21+
22+
@override
23+
void dispose() {
24+
_buttonFocusNode.dispose();
25+
super.dispose();
26+
}
27+
28+
@override
29+
Widget build(BuildContext context) {
30+
return MenuAnchor(
31+
childFocusNode: _buttonFocusNode,
32+
menuChildren: <Widget>[
33+
MenuItemButton(
34+
onPressed: () {},
35+
child: const Text('Revert'),
36+
),
37+
MenuItemButton(
38+
onPressed: () {},
39+
child: const Text('Setting'),
40+
),
41+
MenuItemButton(
42+
onPressed: () {},
43+
child: const Text('Send Feedback'),
44+
),
45+
],
46+
builder: (_, MenuController controller, Widget? child) {
47+
return IconButton(
48+
focusNode: _buttonFocusNode,
49+
onPressed: () {
50+
if (controller.isOpen) {
51+
controller.close();
52+
} else {
53+
controller.open();
54+
}
55+
},
56+
icon: const Icon(Icons.more_vert),
57+
);
58+
},
59+
);
60+
}
61+
}
62+
63+
/// Top Level Application Widget.
64+
class SimpleCascadingMenuApp extends StatelessWidget {
65+
const SimpleCascadingMenuApp({super.key});
66+
67+
@override
68+
Widget build(BuildContext context) {
69+
return MaterialApp(
70+
debugShowCheckedModeBanner: false,
71+
home: Scaffold(
72+
appBar: AppBar(
73+
title: const Text('MenuAnchor Simple Example'),
74+
actions: const <Widget>[
75+
MyCascadingMenu(),
76+
],
77+
),
78+
),
79+
);
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/menu_anchor/menu_anchor.3.dart' as example;
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
void main() {
10+
testWidgets('Menu button opens and closes the menu', (WidgetTester tester) async {
11+
await tester.pumpWidget(const example.SimpleCascadingMenuApp());
12+
13+
// Find the menu button.
14+
final Finder menuButton = find.byType(IconButton);
15+
expect(menuButton, findsOneWidget);
16+
17+
// Tap the menu button to open the menu.
18+
await tester.tap(menuButton);
19+
await tester.pumpAndSettle();
20+
21+
// Verify that the menu is open.
22+
expect(find.text('Revert'), findsOneWidget);
23+
24+
// Tap the menu button again to close the menu.
25+
await tester.tap(menuButton);
26+
await tester.pumpAndSettle();
27+
28+
// Verify that the menu is closed.
29+
expect(find.text('Revert'), findsNothing);
30+
});
31+
32+
testWidgets('Does not show debug banner', (WidgetTester tester) async {
33+
await tester.pumpWidget(const example.SimpleCascadingMenuApp());
34+
expect(find.byType(CheckedModeBanner), findsNothing);
35+
});
36+
}

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

+7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ typedef MenuAnchorChildBuilder = Widget Function(
119119
///
120120
/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.1.dart **
121121
/// {@end-tool}
122+
///
123+
/// {@tool dartpad}
124+
/// This example demonstrates a simplified cascading menu using the [MenuAnchor]
125+
/// widget.
126+
///
127+
/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.3.dart **
128+
/// {@end-tool}
122129
class MenuAnchor extends StatefulWidget {
123130
/// Creates a const [MenuAnchor].
124131
///

0 commit comments

Comments
 (0)