flutter_fancy_side_menu
一个带缩放、旋转、圆角与平移动画的侧滑菜单组件,支持 LTR/RTL、手势拖拽、点击回调与头尾区域自定义。
适合在 App 中快速接入“炫酷”的侧边菜单效果,同时保留充分的自定义能力。
特性
- 侧滑打开/关闭,支持手势左右滑动
- 动画可配:缩放 scale、旋转 angle、圆角 radius、平移 xTranslate、时长 duration
- 可配置菜单宽度、背景色、遮罩层(阻止主内容点击)
- 支持 LTR 和 RTL 文本方向
- Header/Footer 自定义
- 点击菜单项回调返回 index
安装
在你的项目 pubspec.yaml 中加入依赖:
dependencies:
flutter_fancy_side_menu: ^0.0.1
然后执行依赖安装。
快速开始
import 'package:flutter/material.dart';
import 'package:flutter_fancy_side_menu/flutter_fancy_side_menu.dart';
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
final menuKey = GlobalKey<FancySideMenuState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Fancy Side Menu'),
leading: IconButton(
icon: const Icon(Icons.menu),
onPressed: () => menuKey.currentState?.toggle(),
),
),
body: FancySideMenu(
key: menuKey,
items: const [
Padding(padding: EdgeInsets.all(16), child: Text('Home')),
Padding(padding: EdgeInsets.all(16), child: Text('Profile')),
Padding(padding: EdgeInsets.all(16), child: Text('Settings')),
],
onSideMenuTap: (index) {
debugPrint('Tapped index: $index');
},
header: const Padding(
padding: EdgeInsets.only(left: 20, top: 40),
child: CircleAvatar(radius: 36, child: Text('U')),
),
footer: const Padding(
padding: EdgeInsets.only(left: 20, bottom: 20),
child: Text('v0.0.1'),
),
body: Container(
color: Colors.white,
alignment: Alignment.center,
child: const Text('Content Area'),
),
// 可选:动画/外观参数
xTranslate: 300,
scaleSize: 0.9,
angleSize: -0.06,
bodyRadiusSize: 20,
toggleDuration: const Duration(milliseconds: 200),
backgroundColor: const Color.fromRGBO(145, 204, 117, 1),
sideWidth: 240,
mask: false,
// direction: TextDirection.rtl,
),
);
}
}
参数说明(API)
- items • List
- body • Widget • 必填:主内容区域
- onSideMenuTap • Function(index) • 必填:点击菜单项回调,参数为下标
- sideWidth • double • 默认 240.0:菜单面板的宽度
- toggleDuration • Duration • 默认 200ms:打开/关闭动画时长
- header • Widget? • 默认
SizedBox(height: 200):顶部自定义区域 - footer • Widget? • 默认
SizedBox(height: 40):底部自定义区域 - backgroundColor • Color • 默认
Color.fromRGBO(145, 204, 117, 1):菜单背景色 - mask • bool • 默认 false:为 true 时在 body 上加遮罩,阻止点击
- scaleSize • double • 默认 0.7:打开时的缩放比例(1.0 为不缩放)
- angleSize • double • 默认 -0.12:打开时的旋转弧度(单位为弧度,非度数)
- bodyRadiusSize • double • 默认 20.0:打开时 body 圆角
- xTranslate • double • 默认 300.0:打开时 body 的水平位移
- direction • TextDirection • 默认
TextDirection.ltr:文本方向,影响打开方向和动画
说明:
toggle():通过绑定的GlobalKey<FancySideMenuState>可在外部手动打开/关闭菜单。- 手势:左右滑动可打开或关闭(带 10px 阈值)。
进阶用法
- 通过按钮控制开合
final key = GlobalKey<FancySideMenuState>();
// ...
IconButton(icon: const Icon(Icons.menu), onPressed: () => key.currentState?.toggle())
- RTL 支持
FancySideMenu(
direction: TextDirection.rtl,
// 其他参数...
)
- 遮罩拦截点击
FancySideMenu(
mask: true, // 打开时在 body 顶部添加透明遮罩以拦截点击
// 其他参数...
)
示例
查看 example/ 目录获取一个可运行的完整示例(包含 Android/iOS/Web 支持)。
运行示例:
flutter pub get
flutter run -d chrome # 或选择你的设备
测试
本仓库包含基础的 Widget 测试。
flutter test
常见问题(FAQ)
-
Q: body 上的点击在打开时仍然触发怎么办? A: 传入
mask: true会在 body 顶部加一层透明遮罩,用于拦截点击。 -
Q: 如何只改变位移而不缩放/旋转? A: 设置
scaleSize: 1.0、angleSize: 0.0即可。 -
Q: 我需要从右往左打开菜单? A: 将
direction设为TextDirection.rtl。
变更日志与协议
- 变更日志:见
CHANGELOG.md - 许可证:见
LICENSE