Flutter级联菜单插件cascading_menu的使用

Flutter级联菜单插件cascading_menu的使用

简介

cascading_menu 是一个用于实现级联菜单功能的 Flutter 插件。它支持多层级菜单、垂直或水平方向的菜单布局,并且可以作为菜单或侧边栏使用。此外,该插件还支持上下文菜单区域和菜单按钮小部件,适合在桌面和移动平台上使用。

特性

  • 支持多层级菜单。
  • 可以设置菜单的方向为垂直或水平。
  • 可以用作菜单或侧边栏。
  • 提供上下文菜单区域和菜单按钮小部件。
  • 提供丰富的菜单样式。
  • 支持单选、复选和滑动菜单项。
  • 支持通过快捷键激活菜单项。
  • 在桌面和移动平台上均可使用。

使用示例

以下是一个完整的示例代码,展示如何使用 cascading_menu 插件创建一个简单的级联菜单应用。

完整代码示例

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:cascading_menu/cascading_menu.dart';

void main() {
  runApp(const ExampleApp());
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cascading Menu Example',
      home: ExamplePage(),
    );
  }
}

class ExamplePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Cascading Menu Example'),
        actions: [
          // 菜单按钮
          MenuButton(
            menu: Menu(
              items: [
                MenuItem(
                  title: const Text('Toogle Brightness'),
                  shortcutActivator: const SingleActivator(LogicalKeyboardKey.keyB, control: true),
                ),
                MenuItem(
                  title: const Text('Interea Venientum'),
                  onPressed: () {},
                ),
              ],
            ),
          ),
        ],
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: ExampleRegion(
            'Region with vertical menu',
            menuAxis: Axis.vertical,
          ),
        ),
      ),
    );
  }
}

class ExampleRegion extends StatelessWidget {
  final String text;
  final Axis menuAxis;

  const ExampleRegion(this.text, {Key? key, required this.menuAxis})
      : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ContextMenuRegion(
      menuAxis: menuAxis,
      menu: buildMenu(menuAxis),
      child: Container(
        alignment: Alignment.center,
        padding: const EdgeInsets.all(16.0),
        decoration: BoxDecoration(
          color: Colors.grey[200],
          borderRadius: BorderRadius.circular(8.0),
        ),
        child: Text(text, style: TextStyle(fontSize: 18)),
      ),
    );
  }

  Menu buildMenu(Axis axis) {
    return Menu(
      items: [
        MenuItem(
          title: const Text('Ad Astra'),
          shortcutActivator: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
        ),
        if (axis == Axis.vertical)
          MenuItem(
            title: const Text('Haec Concordia'),
            onPressed: () {},
          ),
        MenuItem(
          title: const Text('Arrange'),
          submenu: Menu(
            items: [
              MenuItem(
                title: const Text('Move Up'),
                shortcutActivator: const SingleActivator(LogicalKeyboardKey.arrowUp, alt: true),
              ),
              MenuItem(
                title: const Text('Move Down'),
                shortcutActivator: const SingleActivator(LogicalKeyboardKey.arrowDown, alt: true),
              ),
            ],
          ),
        ),
        MenuItem(
          leading: const Icon(Icons.star_outlined),
          title: const Text('Appearance'),
          submenu: Menu(
            items: [
              MenuItem(
                title: const Text('Fill'),
                leading: const Icon(Icons.format_color_fill_outlined),
                submenu: Menu(
                  items: [
                    MenuRadioGroup<String>(
                      values: {
                        'None': 'None',
                        'Red': 'Red',
                        'Yellow': 'Yellow',
                        'Green': 'Green',
                        'Blue': 'Blue',
                      },
                      groupValue: 'None',
                      onChanged: (value) {},
                      controlAffinity: MenuItemControlAffinity.trailing,
                    ),
                  ],
                ),
              ),
              MenuItem(
                leading: const Icon(Icons.text_format_outlined),
                title: const Text('Font'),
                submenu: Menu(
                  items: [
                    SliderMenuItem(
                      title: const Text('Size'),
                      value: 16.0,
                      onChanged: (value) {},
                      min: 10.0,
                      max: 30.0,
                      divisions: 10,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
        const MenuDivider(),
        MenuItem(
          leading: const Icon(Icons.emoji_emotions),
          title: const Text('Conformeu'),
          shortcutActivator: const SingleActivator(LogicalKeyboardKey.keyR, control: true),
        ),
        const MenuDivider(),
        if (axis == Axis.vertical)
          MenuItem(
            title: const Text('Interea Venientum'),
            onPressed: () {},
          ),
        if (axis == Axis.vertical)
          MenuItem(
            leading: const Icon(Icons.assessment),
            title: const Text('Tellure Levatur'),
            shortcutActivator: const SingleActivator(LogicalKeyboardKey.keyT, alt: true),
          ),
      ],
    );
  }
}

更多关于Flutter级联菜单插件cascading_menu的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter级联菜单插件cascading_menu的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


cascading_menu 是一个用于在 Flutter 应用中创建级联菜单的插件。级联菜单通常用于在用户点击某个按钮或选项时,显示一个下拉菜单,并且该菜单可以进一步展开子菜单。这种菜单结构在桌面应用程序中非常常见,但在移动应用中也可以使用。

安装 cascading_menu 插件

首先,你需要在 pubspec.yaml 文件中添加 cascading_menu 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  cascading_menu: ^1.0.0  # 请检查最新版本

然后运行 flutter pub get 来安装依赖。

使用 cascading_menu

以下是一个简单的示例,展示如何使用 cascading_menu 插件创建一个级联菜单。

import 'package:flutter/material.dart';
import 'package:cascading_menu/cascading_menu.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Cascading Menu Example'),
        ),
        body: Center(
          child: CascadingMenu(
            menuItems: [
              MenuItem(
                title: 'File',
                children: [
                  MenuItem(
                    title: 'New',
                    onTap: () {
                      print('New clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Open',
                    onTap: () {
                      print('Open clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Save',
                    onTap: () {
                      print('Save clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Exit',
                    onTap: () {
                      print('Exit clicked');
                    },
                  ),
                ],
              ),
              MenuItem(
                title: 'Edit',
                children: [
                  MenuItem(
                    title: 'Undo',
                    onTap: () {
                      print('Undo clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Redo',
                    onTap: () {
                      print('Redo clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Cut',
                    onTap: () {
                      print('Cut clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Copy',
                    onTap: () {
                      print('Copy clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Paste',
                    onTap: () {
                      print('Paste clicked');
                    },
                  ),
                ],
              ),
              MenuItem(
                title: 'View',
                children: [
                  MenuItem(
                    title: 'Zoom In',
                    onTap: () {
                      print('Zoom In clicked');
                    },
                  ),
                  MenuItem(
                    title: 'Zoom Out',
                    onTap: () {
                      print('Zoom Out clicked');
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

解释

  1. CascadingMenu: 这是级联菜单的主控件。它接受一个 menuItems 参数,该参数是一个 MenuItem 的列表。

  2. MenuItem: 每个 MenuItem 代表一个菜单项。它可以有一个 title(菜单项的标题),一个 onTap 回调(当用户点击该菜单项时触发),以及一个 children 列表(用于定义子菜单项)。

  3. onTap: 当用户点击某个菜单项时,onTap 回调会被触发。你可以在这里执行任何你需要的操作,比如导航到另一个页面或执行某个操作。

自定义样式

你可以通过 CascadingMenustyle 参数来自定义菜单的样式。例如,你可以设置菜单的背景颜色、文本颜色、边框等。

CascadingMenu(
  style: MenuStyle(
    backgroundColor: Colors.blueGrey,
    textStyle: TextStyle(color: Colors.white),
    border: Border.all(color: Colors.white),
  ),
  menuItems: [
    // 菜单项
  ],
)
回到顶部