Flutter可拖拽圆形菜单插件draggable_circular_menu的使用

Flutter可拖拽圆形菜单插件draggable_circular_menu的使用

一个简单的带有动画的圆形菜单插件,可以调整半径、颜色、对齐方式、动画曲线和动画时长。

底部中心 底部左侧 底部右侧
居中 居中左侧
居中右侧 顶部中心
顶部左侧 顶部右侧
多圆形菜单

开始使用

安装

pubspec.yaml 文件中添加以下依赖:

draggable_circular_menu : ^latest_version

然后在项目根目录下运行:

flutter pub get

基本用法

首先,在你的项目文件中导入该插件:

import 'package:draggable_circular_menu/draggable_circular_menu.dart';

然后,以最简单的方式添加圆形菜单:

final circularMenu = CircularMenu(items: [
    CircularMenuItem(icon: Icons.home, onTap: () {
      // 回调函数
    }),
    CircularMenuItem(icon: Icons.search, onTap: () {
      // 回调函数
    }),
    CircularMenuItem(icon: Icons.settings, onTap: () {
      // 回调函数
    }),
    CircularMenuItem(icon: Icons.star, onTap: () {
      // 回调函数
    }),
    CircularMenuItem(icon: Icons.pages, onTap: () {
      // 回调函数
    }),
  ]);

可选参数

你还可以通过一些可选参数来初始化菜单,例如:

final circularMenu = CircularMenu(
      // 菜单对齐方式
      alignment: Alignment.bottomCenter,
      // 菜单半径
      radius: 100,
      // 背景小部件,用于显示实际页面内容
      backgroundWidget: MyCustomWidget(),
      // 全局键,用于在代码中的任何位置控制动画
      key: GlobalKey<CircularMenuState>(),
      // 动画持续时间
      animationDuration: Duration(milliseconds: 500),
      // 动画向前曲线
      curve: Curves.bounceOut,
      // 动画向后曲线
      reverseCurve: Curves.fastOutSlowIn,
      // 第一个项目角度
      startingAngleInRadian: 0,
      // 最后一个项目角度
      endingAngleInRadian: pi,
      // 切换按钮回调
      toggleButtonOnPressed: () {
        // 回调函数
      },
      // 切换按钮颜色
      toggleButtonColor: Colors.pink,
      // 切换按钮阴影
      toggleButtonBoxShadow: [
        BoxShadow(
          color: Colors.blue,
          blurRadius: 10,
        ),
      ], 
      // 切换按钮图标颜色
      toggleButtonIconColor: Colors.white,
      // 切换按钮边距
      toggleButtonMargin: 10.0,
      // 切换按钮内边距
      toggleButtonPadding: 10.0,
      // 切换按钮大小
      toggleButtonSize: 40.0,
      // 菜单项列表
      items: [
        CircularMenuItem(
          // 菜单项回调函数
          onTap: () {
            // 回调函数
          },
          // 菜单项外观属性
          icon: Icons.home,
          color: Colors.blue,
          elevation: 4.0,
          iconColor: Colors.white,
          iconSize: 30.0,
          margin: 10.0,
          padding: 10.0,
          // 当传递了AnimatedIcon时,上述'icon'将被忽略
          animatedIcon: AnimatedIcon(),
        ),
        CircularMenuItem(
            icon: Icons.search,
            onTap: () {
              // 回调函数
            }),
        CircularMenuItem(
            icon: Icons.settings,
            onTap: () {
              // 回调函数
            }),
        CircularMenuItem(
            icon: Icons.star,
            onTap: () {
              // 回调函数
            }),
        CircularMenuItem(
            icon: Icons.pages,
            onTap: () {
              // 回调函数
            }),
      ]);

添加徽章

可以通过设置 enableBadge 属性为 true 来为 CircularMenuItem 添加徽章:

CircularMenuItem(
              enableBadge: true,
            )

还可以自定义徽章,通过设置 badgeColorbadgeLabelbadgeRadiusbadgeTextColorbadgeRightOffsetbadgeTopOffsetbadgeBottomOffsetbadgeLeftOffset 等参数:

CircularMenuItem(
              enableBadge: true,
              badgeColor: Colors.amber,
              badgeLabel: '3',
              badgeRadius: 15,
              badgeTextColor: Colors.white,
              badgeRightOffset: 0,
              badgeTopOffset: 0,
              onTap: () {
                print('徽章在圆形菜单项上点击');
              },
              icon: Icons.home,
              color: Colors.teal,
            )

控制动画

你可以通过全局键在代码的任何地方控制动画:

GlobalKey<CircularMenuState> key = GlobalKey<CircularMenuState>();

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      backgroundColor: Colors.pink,
      title: Text(
        'Flutter 圆形菜单',
        style: TextStyle(
          color: Colors.white,
        ),
      ),
    ),
    body: CircularMenu(
      alignment: Alignment.bottomCenter,
      startingAngleInRadian: 1.25 * pi,
      endingAngleInRadian: 1.75 * pi,
      backgroundWidget: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            MaterialButton(
              onPressed: () {
                key.currentState.forwardAnimation();
              },
              color: Colors.pink,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15)),
              padding: const EdgeInsets.all(15),
              child: Text(
                '正向',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
            MaterialButton(
              onPressed: () {
                key.currentState.reverseAnimation();
              },
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15)),
              padding: const EdgeInsets.all(15),
              color: Colors.pink,
              child: Text(
                '反向',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
          ],
        ),
      ),
      key: key,
      items: [
        CircularMenuItem(
          icon: Icons.home,
          onTap: () {},
          color: Colors.green,
          iconColor: Colors.white,
        ),
        CircularMenuItem(
          icon: Icons.search,
          onTap: () {},
          color: Colors.orange,
          iconColor: Colors.white,
        ),
        CircularMenuItem(
          icon: Icons.settings,
          onTap: () {},
          color: Colors.deepPurple,
          iconColor: Colors.white,
        ),
      ],
    ),
  );
}

多个圆形菜单

你也可以使用 MultiCircularMenu 显示多个菜单在同一小部件中:

MultiCircularMenu(
      backgroundWidget: Center(
        child: Text(
          "Flutter 圆形菜单",
          style: TextStyle(
            fontWeight: FontWeight.bold,
            fontSize: 25,
          ),
        ),
      ),
      menus: [
        CircularMenu(
            toggleButtonColor: Colors.pink,
            alignment: Alignment.bottomLeft,
            items: [
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.search,
                color: Colors.blue,
              ),
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.home,
                color: Colors.grey,
              ),
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.settings,
                color: Colors.green,
              ),
            ]),
        CircularMenu(
            toggleButtonColor: Colors.deepPurpleAccent,
            alignment: Alignment.bottomRight,
            items: [
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.save,
                color: Colors.teal,
              ),
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.filter,
                color: Colors.amber,
              ),
              CircularMenuItem(
                onTap: () {
                  print('点击了');
                },
                icon: Icons.star_border,
                color: Colors.lightGreen,
              ),
            ]),
      ])

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用draggable_circular_menu插件的示例代码。这个插件允许你创建一个可拖拽的圆形菜单。

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

dependencies:
  flutter:
    sdk: flutter
  draggable_circular_menu: ^latest_version  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来,你可以在你的Flutter应用中使用这个插件。以下是一个完整的示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Circular Menu Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  double _menuRadius = 200.0;
  Offset _menuPosition = Offset(300, 300);
  double _angleStep = 60.0; // 60 degrees step for 6 items

  List<IconData> _menuIcons = [
    Icons.home,
    Icons.settings,
    Icons.add,
    Icons.edit,
    Icons.delete,
    Icons.share,
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Draggable Circular Menu Example'),
      ),
      body: Stack(
        children: <Widget>[
          Positioned(
            left: _menuPosition.dx - _menuRadius,
            top: _menuPosition.dy - _menuRadius,
            child: DraggableCircularMenu(
              radius: _menuRadius,
              position: _menuPosition,
              onPositionChanged: (newPosition) {
                setState(() {
                  _menuPosition = newPosition;
                });
              },
              angleStep: _angleStep,
              children: List.generate(_menuIcons.length, (index) {
                final angle = _angleStep * index * (Math.pi / 180);
                final x = _menuRadius * Math.cos(angle);
                final y = _menuRadius * Math.sin(angle);
                return Positioned(
                  left: _menuPosition.dx + x,
                  top: _menuPosition.dy + y,
                  child: GestureDetector(
                    onTap: () {
                      // Handle menu item tap
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(content: Text('Tapped: ${_menuIcons[index]}')),
                      );
                    },
                    child: Icon(
                      _menuIcons[index],
                      size: 48,
                      color: Colors.blue,
                    ),
                  ),
                );
              }),
            ),
          ),
        ],
      ),
    );
  }
}

在这个示例中:

  1. 我们首先导入了必要的包,包括flutter/material.dartdraggable_circular_menu.dart
  2. 然后在MyApp类中,我们设置了基本的Material应用。
  3. MyHomePage类中,我们定义了菜单的半径、位置、角度步长以及菜单项图标。
  4. 使用DraggableCircularMenu组件创建了一个可拖拽的圆形菜单,并处理菜单项的位置变化。
  5. 每个菜单项都是一个GestureDetector包裹的Icon,点击时会显示一个SnackBar。

请注意,DraggableCircularMenu组件本身并不直接提供在draggable_circular_menu包中,因此上述代码展示了如何自己实现一个可拖拽的圆形菜单效果。你可以根据实际需求调整角度计算、图标、动画等细节。如果draggable_circular_menu包未来提供了直接的组件,请参考其官方文档进行使用。

回到顶部