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