// 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 '../../gallery/demo.dart'; class MenuDemo extends StatefulWidget { const MenuDemo({super.key}); static const String routeName = '/material/menu'; @override MenuDemoState createState() => MenuDemoState(); } class MenuDemoState extends State { final String _simpleValue1 = 'Menu item value one'; final String _simpleValue2 = 'Menu item value two'; final String _simpleValue3 = 'Menu item value three'; String? _simpleValue; final String _checkedValue1 = 'One'; final String _checkedValue2 = 'Two'; final String _checkedValue3 = 'Free'; final String _checkedValue4 = 'Four'; late List _checkedValues; @override void initState() { super.initState(); _simpleValue = _simpleValue2; _checkedValues = [_checkedValue3]; } void showInSnackBar(String value) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(value))); } void showMenuSelection(String value) { if ([_simpleValue1, _simpleValue2, _simpleValue3].contains(value)) { setState(() => _simpleValue = value); } showInSnackBar('You selected: $value'); } void showCheckedMenuSelections(String value) { if (_checkedValues.contains(value)) { _checkedValues.remove(value); } else { _checkedValues.add(value); } showInSnackBar('Checked $_checkedValues'); } bool isChecked(String value) => _checkedValues.contains(value); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Menus'), actions: [ MaterialDemoDocumentationButton(MenuDemo.routeName), PopupMenuButton( onSelected: showMenuSelection, itemBuilder: (BuildContext context) => >[ const PopupMenuItem(value: 'Toolbar menu', child: Text('Toolbar menu')), const PopupMenuItem(value: 'Right here', child: Text('Right here')), const PopupMenuItem(value: 'Hooray!', child: Text('Hooray!')), ], ), ], ), body: ListTileTheme( iconColor: Theme.brightnessOf(context) == Brightness.light ? Colors.grey[600] : Colors.grey[500], child: ListView( padding: kMaterialListPadding, children: [ // Pressing the PopupMenuButton on the right of this item shows // a simple menu with one disabled item. Typically the contents // of this "contextual menu" would reflect the app's state. ListTile( title: const Text('An item with a context menu button'), trailing: PopupMenuButton( padding: EdgeInsets.zero, onSelected: showMenuSelection, itemBuilder: (BuildContext context) => >[ PopupMenuItem( value: _simpleValue1, child: const Text('Context menu item one'), ), const PopupMenuItem(enabled: false, child: Text('A disabled menu item')), PopupMenuItem( value: _simpleValue3, child: const Text('Context menu item three'), ), ], ), ), // Pressing the PopupMenuButton on the right of this item shows // a menu whose items have text labels and icons and a divider // That separates the first three items from the last one. ListTile( title: const Text('An item with a sectioned menu'), trailing: PopupMenuButton( padding: EdgeInsets.zero, onSelected: showMenuSelection, itemBuilder: (BuildContext context) => >[ const PopupMenuItem( value: 'Preview', child: ListTile(leading: Icon(Icons.visibility), title: Text('Preview')), ), const PopupMenuItem( value: 'Share', child: ListTile(leading: Icon(Icons.person_add), title: Text('Share')), ), const PopupMenuItem( value: 'Get Link', child: ListTile(leading: Icon(Icons.link), title: Text('Get link')), ), const PopupMenuDivider(), const PopupMenuItem( value: 'Remove', child: ListTile(leading: Icon(Icons.delete), title: Text('Remove')), ), ], ), ), // This entire list item is a PopupMenuButton. Tapping anywhere shows // a menu whose current value is highlighted and aligned over the // list item's center line. PopupMenuButton( padding: EdgeInsets.zero, initialValue: _simpleValue, onSelected: showMenuSelection, child: ListTile( title: const Text('An item with a simple menu'), subtitle: Text(_simpleValue!), ), itemBuilder: (BuildContext context) => >[ PopupMenuItem(value: _simpleValue1, child: Text(_simpleValue1)), PopupMenuItem(value: _simpleValue2, child: Text(_simpleValue2)), PopupMenuItem(value: _simpleValue3, child: Text(_simpleValue3)), ], ), // Pressing the PopupMenuButton on the right of this item shows a menu // whose items have checked icons that reflect this app's state. ListTile( title: const Text('An item with a checklist menu'), trailing: PopupMenuButton( padding: EdgeInsets.zero, onSelected: showCheckedMenuSelections, itemBuilder: (BuildContext context) => >[ CheckedPopupMenuItem( value: _checkedValue1, checked: isChecked(_checkedValue1), child: Text(_checkedValue1), ), CheckedPopupMenuItem( value: _checkedValue2, enabled: false, checked: isChecked(_checkedValue2), child: Text(_checkedValue2), ), CheckedPopupMenuItem( value: _checkedValue3, checked: isChecked(_checkedValue3), child: Text(_checkedValue3), ), CheckedPopupMenuItem( value: _checkedValue4, checked: isChecked(_checkedValue4), child: Text(_checkedValue4), ), ], ), ), ], ), ), ); } }