Flutter折叠菜单插件folding_menu的使用
Flutter折叠菜单插件folding_menu的使用
这是一个用于在Flutter应用中添加折叠菜单的简单包。
示例
使用
要使用此插件,只需将其添加到Stack
小部件中(通常作为最后一个子元素):
body: Stack(
children: [
Container(
color: Colors.deepOrange,
child: Center(child: Text("其他屏幕内容", style: TextStyle(color: Colors.white, fontSize: 20))),
),
// 将FoldingMenu作为Stack的最后一个子元素添加
FoldingMenu(
duration: Duration(milliseconds: 900),
shadowColor: Colors.black26,
animationCurve: Curves.decelerate,
folded: openMenu,
children: [
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 1")
));
},
title: Text("家庭舞蹈"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 2")
));
},
title: Text("家庭舞蹈 2"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 3")
));
},
title: Text("家庭舞蹈 3"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 4")
));
},
title: Text("家庭舞蹈 4"),
tileColor: Colors.white,
),
],
),
],
),
主页
class MyHomePage extends StatefulWidget {
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool openMenu = false;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepOrange,
title: Text("折叠菜单"),
actions: [
IconButton(
icon: Icon(Icons.menu),
onPressed: () {
setState(() {
openMenu = !openMenu;
});
},
),
],
),
body: Stack(
children: [
ScreenContent(),
AnimatedOpacity(
opacity: openMenu ? 1.0 : 0.0,
duration: Duration(milliseconds: 400),
child: Container(
color: Colors.black54,
child: Center(child: Text("")),
),
),
// 将FoldingMenu作为Stack的最后一个子元素添加
FoldingMenu(
duration: Duration(milliseconds: 900),
shadowColor: Colors.black26,
animationCurve: Curves.decelerate,
folded: openMenu,
children: [
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 1")
));
},
title: Text("屏幕 1"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 2")
));
},
title: Text("屏幕 2"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 3")
));
},
title: Text("屏幕 3"),
tileColor: Colors.white,
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SecondScreen(text: "页面 4")
));
},
title: Text("屏幕 4"),
tileColor: Colors.white,
),
],
),
],
),
);
}
}
屏幕内容
class ScreenContent extends StatefulWidget {
[@override](/user/override)
_ScreenContentState createState() => _ScreenContentState();
}
class _ScreenContentState extends State<ScreenContent> {
[@override](/user/override)
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"音乐专辑",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Expanded(child: Center()),
IconButton(icon: Icon(Icons.shopping_cart), onPressed: () {}),
CircleAvatar(
child: Image.asset("assets/images/dp_default.png"),
),
],
),
SizedBox(height: 10),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "查找您的兴趣!",
fillColor: Colors.grey.shade200,
filled: true,
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
DropdownButton(
style: TextStyle(fontSize: 15, color: Colors.black),
icon: Icon(Icons.keyboard_arrow_down),
underline: Container(color: Colors.white),
items: ["特色", "最热门", "最新", "受欢迎"]
.map((e) => DropdownMenuItem(
child: Text(e),
value: e,
))
.toList(),
onChanged: (newItem) {},
),
IconButton(icon: Icon(Icons.sort), onPressed: () {}),
],
),
SizedBox(height: 10),
Expanded(
child: GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
.map((e) => Card(
child: Column(
children: [
Image.asset("assets/images/image_$e.jpg"),
],
),
))
.toList(),
),
),
],
),
),
);
}
}
更多关于Flutter折叠菜单插件folding_menu的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter折叠菜单插件folding_menu的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用folding_menu
插件的一个基本示例。这个插件允许你创建一个可折叠的菜单,非常适合在移动应用中提供导航或快速访问功能。
首先,确保你已经在pubspec.yaml
文件中添加了folding_menu
依赖:
dependencies:
flutter:
sdk: flutter
folding_menu: ^最新版本号 # 请替换为实际可用的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下方式使用folding_menu
:
import 'package:flutter/material.dart';
import 'package:folding_menu/folding_menu.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Folding Menu Demo'),
),
body: Center(
child: FoldingMenu(
// 菜单按钮的初始位置
initialAngle: 0.0,
// 菜单项
items: [
FoldingMenuItem(
icon: Icons.home,
title: 'Home',
onTap: () {
// 点击事件处理
Navigator.pushNamed(context, '/home');
},
),
FoldingMenuItem(
icon: Icons.settings,
title: 'Settings',
onTap: () {
// 点击事件处理
Navigator.pushNamed(context, '/settings');
},
),
FoldingMenuItem(
icon: Icons.account_circle,
title: 'Profile',
onTap: () {
// 点击事件处理
Navigator.pushNamed(context, '/profile');
},
),
],
// 菜单打开/关闭时的回调
onChanged: (isOpen) {
print('Menu is now ${isOpen ? 'open' : 'closed'}');
},
// 菜单动画持续时间
duration: Duration(milliseconds: 300),
// 菜单按钮的背景颜色
backgroundColor: Colors.blue,
// 菜单按钮的大小
buttonSize: 56.0,
),
),
),
);
}
}
// 路由设置(示例)
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Text('This is the home page!'),
),
);
}
}
class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Settings Page'),
),
body: Center(
child: Text('This is the settings page!'),
),
);
}
}
class ProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Profile Page'),
),
body: Center(
child: Text('This is the profile page!'),
),
);
}
}
// 路由配置
class MyRouterDelegate extends RouterDelegate<String>
with ChangeNotifier, PopNavigatorRouterDelegate<String> {
@override
final GlobalKey<NavigatorState> navigatorKey;
MyRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
_updateRoutes();
}
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: _pages,
onGenerateRoute: (settings) {
if (settings.name == '/') {
return MaterialPageRoute(builder: (_) => MyHomePage());
} else if (settings.name == '/settings') {
return MaterialPageRoute(builder: (_) => SettingsPage());
} else if (settings.name == '/profile') {
return MaterialPageRoute(builder: (_) => ProfilePage());
}
return null;
},
);
}
List<Page<String>> _pages = [];
void _updateRoutes() {
_pages = [
MaterialPage<String>(key: ValueKey('home'), child: MyHomePage(), arguments: '/')
];
notifyListeners();
}
@override
String get currentConfiguration => '/';
@override
Future<void> setNewRoutePath(String path) async {
if (path == '/') {
_pages = [
MaterialPage<String>(key: ValueKey('home'), child: MyHomePage(), arguments: '/')
];
} else if (path == '/settings') {
_pages = [
MaterialPage<String>(key: ValueKey('home'), child: MyHomePage(), arguments: '/'),
MaterialPage<String>(key: ValueKey('settings'), child: SettingsPage(), arguments: '/settings')
];
} else if (path == '/profile') {
_pages = [
MaterialPage<String>(key: ValueKey('home'), child: MyHomePage(), arguments: '/'),
MaterialPage<String>(key: ValueKey('profile'), child: ProfilePage(), arguments: '/profile')
];
}
notifyListeners();
}
}
class MyRouterInformationParser extends RouterInformationParser<String> {
@override
Future<String> parseRouteInformation(RouteInformation routeInformation) async {
final uri = Uri.parse(routeInformation.location ?? '/');
return uri.pathSegments.isNotEmpty ? uri.pathSegments.first : '/';
}
@override
RouteInformation restoreRouteInformation(String configuration) {
if (configuration == '/') {
return RouteInformation(location: '/');
} else {
return RouteInformation(location: '/$configuration');
}
}
}
class MyAppRouter extends MaterialApp {
MyAppRouter({Key key})
: super(
key: key,
routerDelegate: MyRouterDelegate(),
routeInformationParser: MyRouterInformationParser(),
);
}
void mainRouter() {
runApp(MyAppRouter());
}
注意:上面的代码包含了一个完整的路由设置示例,用于处理菜单项点击后的页面跳转。实际应用中,你可能需要根据具体需求调整这部分代码。mainRouter
函数提供了一个使用MaterialApp.router
的替代启动方式,但在这个示例中,我保留了原始的MaterialApp
结构并在其中嵌入了FoldingMenu
,以便更清晰地展示folding_menu
插件的使用。你可以根据实际需求选择适合的启动方式。
另外,请确保在实际项目中处理路由时,根据具体需求调整页面跳转逻辑和页面结构。上面的路由配置只是为了演示目的。