简体   繁体   English

Flutter 材质抽屉导航到页面

[英]Flutter material drawer navigate to pages

I'm new to Flutter and I'm still learning.我是 Flutter 的新手,我还在学习。

I have created a plutter project with a material driven sidebar by following the tutorial of Techie Blossom我按照 Techie Blossom的教程创建了一个带有材质驱动侧边栏的 plutter 项目

Techie however did not explain how to add navigation to different pages in his tutorial.然而,Techie 在他的教程中没有解释如何为不同的页面添加导航。 I have been wrecking my brain trying to figure out how to do it but no luck yet.我一直在绞尽脑汁想弄清楚怎么做,但还没有运气。

Can you guys please help me.你们能帮我吗。 I have added my project to GitHub where you guys can find the code .我已将我的项目添加到 GitHub,你们可以在那里找到代码

Thank you谢谢

void main() => runApp(MyApp());

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

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        backgroundColor: drawerBackgroundColor,
        title: Text('MD Drawer'),
      ),
      body: BlocProvider<CmdNavBloc>(
        create: (context) => CmdNavBloc(),
        child: Stack(
          children: <Widget>[
            BlocBuilder<CmdNavBloc, NavigationStates>(
              builder: (context, state) {
                if (state is Dashboard) {
                  return DashBoardPage();
                } else if (state is Search) {
                  return SearchPage();
                } else if (state is Notifications) {
                  return SearchPage();
                } else if (state is Errors) {
                  return SearchPage();
                } else if (state is Settings) {
                  return SearchPage();
                }
              },
            ),
            CmdDrawer(),
          ],
        ),
      ),
    );
  }
}

There are many ways to do what you are looking for, but I saw that you were trying to use a Bloc to achieve that.有很多方法可以做你正在寻找的东西,但我看到你试图使用 Bloc 来实现这一目标。 It's a good option, so what you can do is use it, in the MyHomePage class as you can see below:这是一个不错的选择,因此您可以在 MyHomePage 类中使用它,如下所示:

BlocProvider<CmdNavBloc>(
    create: (context) => CmdNavBloc(),
    child: Stack(
      children: <Widget>[
        BlocBuilder<CmdNavBloc, NavigationStates>(
          builder: (context, state) {
            if (state is Dashboard) {
              return DashBoardPage();
            } else {
              if (state is Search) {
                return SearchPage();
              } else {
                ....
              }
            }
          },
        ),
        CmdDrawer(),
      ],
    ),
  ),

Remember that Bloc works with Events and States, so you can add a state for each page as follows in your CmdNavBloc class and also yield this states instead of a Widget:请记住,Bloc 与事件和状态一起使用,因此您可以在 CmdNavBloc 类中为每个页面添加一个状态,并且还生成此状态而不是小部件:

abstract class NavigationStates {}

class Dashboard extends NavigationStates {}

class Search extends NavigationStates {}

...

class CmdNavBloc extends Bloc<NavigationEvents, NavigationStates> {
  @override
  NavigationStates get initialState => Dashboard();

  @override
  Stream<NavigationStates> mapEventToState(NavigationEvents event) async* {
    switch (event) {
      case NavigationEvents.DashboardClickedEvent:
        yield Dashboard();
        break;
      case NavigationEvents.SearchClickedEvent:
        yield Search();
        break;

      ...
    }
  }
}

Next, you have a list of each item to populate in your Menu Drawer, you can add a Event to each item to make the things easy in the navigation, there are a lot of options to achieve this too, but is the easiest by the moment:接下来,您有一个要在 Menu Drawer 中填充的每个项目的列表,您可以向每个项目添加一个 Event 以使导航中的事情变得容易,也有很多选项可以实现此目的,但最简单的是片刻:

class CmdNavModel {
  String title;
  IconData icon;
  NavigationEvents navigationEvent;

  CmdNavModel({this.title, this.icon, this.navigationEvent});
}

List<CmdNavModel> navigationItems = [
  CmdNavModel(
      title: 'Dashboard',
      icon: Icons.insert_chart,
      navigationEvent: NavigationEvents.DashboardClickedEvent),
  CmdNavModel(
      title: 'Search',
      icon: Icons.search,
      navigationEvent: NavigationEvents.SearchClickedEvent),
  CmdNavModel(
      title: 'Notifications',
      icon: Icons.error,
      navigationEvent: NavigationEvents.NotificationsClickedEvent),
  CmdNavModel(
      title: 'Errors',
      icon: Icons.notifications,
      navigationEvent: NavigationEvents.ErrorsClickedEvent),
  CmdNavModel(
      title: 'Settings',
      icon: Icons.settings,
      navigationEvent: NavigationEvents.SettingsClickedEvent),
];

And finally, you can use the Bloc in the CmdDrawer as follows, and add the events to the Bloc from the onTap in your item: `最后,您可以按如下方式使用 CmdDrawer 中的 Bloc,并将事件从项目中的 onTap 添加到 Bloc:`

@override
Widget build(BuildContext context) {
    final CmdNavBloc bloc = BlocProvider.of<CmdNavBloc>(context);

    return AnimatedBuilder(
        animation: _animationController,
        builder: (context, widget) => getWidget(bloc,context, widget),
    );
}

...


Widget getWidget(CmdNavBloc bloc,context, widget) {
    ...
    itemBuilder: (context, counter) {
        return CollapsingListTile(
            onTap: () {
              setState(() {
                bloc.add(navigationItems[counter].navigationEvent);
                currentSelectedIndex = counter;
              });
            },
            isSelected: currentSelectedIndex == counter,
            title: navigationItems[counter].title,
            icon: navigationItems[counter].icon,
            animationController: _animationController,
          );
        },

}

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM