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/services.dart'; |
7 | |
8 | /// Flutter code sample for [RadioMenuButton]. |
9 | |
10 | void main() => runApp(const MenuApp()); |
11 | |
12 | class MyRadioMenu extends StatefulWidget { |
13 | const MyRadioMenu({super.key}); |
14 | |
15 | @override |
16 | State<MyRadioMenu> createState() => _MyRadioMenuState(); |
17 | } |
18 | |
19 | class _MyRadioMenuState extends State<MyRadioMenu> { |
20 | final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button' ); |
21 | Color _backgroundColor = Colors.red; |
22 | late ShortcutRegistryEntry _entry; |
23 | |
24 | static const SingleActivator _redShortcut = SingleActivator(LogicalKeyboardKey.keyR, control: true); |
25 | static const SingleActivator _greenShortcut = SingleActivator(LogicalKeyboardKey.keyG, control: true); |
26 | static const SingleActivator _blueShortcut = SingleActivator(LogicalKeyboardKey.keyB, control: true); |
27 | |
28 | @override |
29 | void didChangeDependencies() { |
30 | super.didChangeDependencies(); |
31 | _entry = ShortcutRegistry.of(context).addAll(<ShortcutActivator, VoidCallbackIntent>{ |
32 | _redShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.red)), |
33 | _greenShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.green)), |
34 | _blueShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.blue)), |
35 | }); |
36 | } |
37 | |
38 | @override |
39 | void dispose() { |
40 | _buttonFocusNode.dispose(); |
41 | _entry.dispose(); |
42 | super.dispose(); |
43 | } |
44 | |
45 | void _setBackgroundColor(Color? color) { |
46 | setState(() { |
47 | _backgroundColor = color!; |
48 | }); |
49 | } |
50 | |
51 | @override |
52 | Widget build(BuildContext context) { |
53 | return Column( |
54 | crossAxisAlignment: CrossAxisAlignment.start, |
55 | children: <Widget>[ |
56 | MenuAnchor( |
57 | childFocusNode: _buttonFocusNode, |
58 | menuChildren: <Widget>[ |
59 | RadioMenuButton<Color>( |
60 | value: Colors.red, |
61 | shortcut: _redShortcut, |
62 | groupValue: _backgroundColor, |
63 | onChanged: _setBackgroundColor, |
64 | child: const Text('Red Background' ), |
65 | ), |
66 | RadioMenuButton<Color>( |
67 | value: Colors.green, |
68 | shortcut: _greenShortcut, |
69 | groupValue: _backgroundColor, |
70 | onChanged: _setBackgroundColor, |
71 | child: const Text('Green Background' ), |
72 | ), |
73 | RadioMenuButton<Color>( |
74 | value: Colors.blue, |
75 | shortcut: _blueShortcut, |
76 | groupValue: _backgroundColor, |
77 | onChanged: _setBackgroundColor, |
78 | child: const Text('Blue Background' ), |
79 | ), |
80 | ], |
81 | builder: (BuildContext context, MenuController controller, Widget? child) { |
82 | return TextButton( |
83 | focusNode: _buttonFocusNode, |
84 | onPressed: () { |
85 | if (controller.isOpen) { |
86 | controller.close(); |
87 | } else { |
88 | controller.open(); |
89 | } |
90 | }, |
91 | child: const Text('OPEN MENU' ), |
92 | ); |
93 | }, |
94 | ), |
95 | Expanded( |
96 | child: Container( |
97 | color: _backgroundColor, |
98 | ), |
99 | ), |
100 | ], |
101 | ); |
102 | } |
103 | } |
104 | |
105 | class MenuApp extends StatelessWidget { |
106 | const MenuApp({super.key}); |
107 | |
108 | @override |
109 | Widget build(BuildContext context) { |
110 | return MaterialApp( |
111 | theme: ThemeData(useMaterial3: true), |
112 | home: const Scaffold(body: SafeArea(child: MyRadioMenu())), |
113 | ); |
114 | } |
115 | } |
116 | |