• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2016 The Chromium 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
5import 'package:flutter/material.dart';
6
7import '../../gallery/demo.dart';
8
9class MenuDemo extends StatefulWidget {
10  const MenuDemo({ Key key }) : super(key: key);
11
12  static const String routeName = '/material/menu';
13
14  @override
15  MenuDemoState createState() => MenuDemoState();
16}
17
18class MenuDemoState extends State<MenuDemo> {
19  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
20
21  final String _simpleValue1 = 'Menu item value one';
22  final String _simpleValue2 = 'Menu item value two';
23  final String _simpleValue3 = 'Menu item value three';
24  String _simpleValue;
25
26  final String _checkedValue1 = 'One';
27  final String _checkedValue2 = 'Two';
28  final String _checkedValue3 = 'Free';
29  final String _checkedValue4 = 'Four';
30  List<String> _checkedValues;
31
32  @override
33  void initState() {
34    super.initState();
35    _simpleValue = _simpleValue2;
36    _checkedValues = <String>[_checkedValue3];
37  }
38
39  void showInSnackBar(String value) {
40    _scaffoldKey.currentState.showSnackBar(SnackBar(
41     content: Text(value),
42    ));
43  }
44
45  void showMenuSelection(String value) {
46    if (<String>[_simpleValue1, _simpleValue2, _simpleValue3].contains(value))
47      _simpleValue = value;
48    showInSnackBar('You selected: $value');
49  }
50
51  void showCheckedMenuSelections(String value) {
52    if (_checkedValues.contains(value))
53      _checkedValues.remove(value);
54    else
55      _checkedValues.add(value);
56
57    showInSnackBar('Checked $_checkedValues');
58  }
59
60  bool isChecked(String value) => _checkedValues.contains(value);
61
62  @override
63  Widget build(BuildContext context) {
64    return Scaffold(
65      key: _scaffoldKey,
66      appBar: AppBar(
67        title: const Text('Menus'),
68        actions: <Widget>[
69          MaterialDemoDocumentationButton(MenuDemo.routeName),
70          PopupMenuButton<String>(
71            onSelected: showMenuSelection,
72            itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
73              const PopupMenuItem<String>(
74                value: 'Toolbar menu',
75                child: Text('Toolbar menu'),
76              ),
77              const PopupMenuItem<String>(
78                value: 'Right here',
79                child: Text('Right here'),
80              ),
81              const PopupMenuItem<String>(
82                value: 'Hooray!',
83                child: Text('Hooray!'),
84              ),
85            ],
86          ),
87        ],
88      ),
89      body: ListView(
90        padding: kMaterialListPadding,
91        children: <Widget>[
92          // Pressing the PopupMenuButton on the right of this item shows
93          // a simple menu with one disabled item. Typically the contents
94          // of this "contextual menu" would reflect the app's state.
95          ListTile(
96            title: const Text('An item with a context menu button'),
97            trailing: PopupMenuButton<String>(
98              padding: EdgeInsets.zero,
99              onSelected: showMenuSelection,
100              itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
101                PopupMenuItem<String>(
102                  value: _simpleValue1,
103                  child: const Text('Context menu item one'),
104                ),
105                const PopupMenuItem<String>(
106                  enabled: false,
107                  child: Text('A disabled menu item'),
108                ),
109                PopupMenuItem<String>(
110                  value: _simpleValue3,
111                  child: const Text('Context menu item three'),
112                ),
113              ],
114            ),
115          ),
116          // Pressing the PopupMenuButton on the right of this item shows
117          // a menu whose items have text labels and icons and a divider
118          // That separates the first three items from the last one.
119          ListTile(
120            title: const Text('An item with a sectioned menu'),
121            trailing: PopupMenuButton<String>(
122              padding: EdgeInsets.zero,
123              onSelected: showMenuSelection,
124              itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
125                const PopupMenuItem<String>(
126                  value: 'Preview',
127                  child: ListTile(
128                    leading: Icon(Icons.visibility),
129                    title: Text('Preview'),
130                  ),
131                ),
132                const PopupMenuItem<String>(
133                  value: 'Share',
134                  child: ListTile(
135                    leading: Icon(Icons.person_add),
136                    title: Text('Share'),
137                  ),
138                ),
139                const PopupMenuItem<String>(
140                  value: 'Get Link',
141                  child: ListTile(
142                    leading: Icon(Icons.link),
143                    title: Text('Get link'),
144                  ),
145                ),
146                const PopupMenuDivider(),
147                const PopupMenuItem<String>(
148                  value: 'Remove',
149                  child: ListTile(
150                    leading: Icon(Icons.delete),
151                    title: Text('Remove'),
152                  ),
153                ),
154              ],
155            ),
156          ),
157          // This entire list item is a PopupMenuButton. Tapping anywhere shows
158          // a menu whose current value is highlighted and aligned over the
159          // list item's center line.
160          PopupMenuButton<String>(
161            padding: EdgeInsets.zero,
162            initialValue: _simpleValue,
163            onSelected: showMenuSelection,
164            child: ListTile(
165              title: const Text('An item with a simple menu'),
166              subtitle: Text(_simpleValue),
167            ),
168            itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
169              PopupMenuItem<String>(
170                value: _simpleValue1,
171                child: Text(_simpleValue1),
172              ),
173              PopupMenuItem<String>(
174                value: _simpleValue2,
175                child: Text(_simpleValue2),
176              ),
177              PopupMenuItem<String>(
178                value: _simpleValue3,
179                child: Text(_simpleValue3),
180              ),
181            ],
182          ),
183          // Pressing the PopupMenuButton on the right of this item shows a menu
184          // whose items have checked icons that reflect this app's state.
185          ListTile(
186            title: const Text('An item with a checklist menu'),
187            trailing: PopupMenuButton<String>(
188              padding: EdgeInsets.zero,
189              onSelected: showCheckedMenuSelections,
190              itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
191                CheckedPopupMenuItem<String>(
192                  value: _checkedValue1,
193                  checked: isChecked(_checkedValue1),
194                  child: Text(_checkedValue1),
195                ),
196                CheckedPopupMenuItem<String>(
197                  value: _checkedValue2,
198                  enabled: false,
199                  checked: isChecked(_checkedValue2),
200                  child: Text(_checkedValue2),
201                ),
202                CheckedPopupMenuItem<String>(
203                  value: _checkedValue3,
204                  checked: isChecked(_checkedValue3),
205                  child: Text(_checkedValue3),
206                ),
207                CheckedPopupMenuItem<String>(
208                  value: _checkedValue4,
209                  checked: isChecked(_checkedValue4),
210                  child: Text(_checkedValue4),
211                ),
212              ],
213            ),
214          ),
215        ],
216      ),
217    );
218  }
219}
220