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

1 回复

更多关于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插件的使用。你可以根据实际需求选择适合的启动方式。

另外,请确保在实际项目中处理路由时,根据具体需求调整页面跳转逻辑和页面结构。上面的路由配置只是为了演示目的。

回到顶部