颤动的材料抽屉导航到页面

时间:2020-03-20 16:05:37

标签: android ios flutter dart

我是Flutter的新手,我还在学习。

我按照Techie Blossom

的教程创建了一个带有材质驱动侧栏的拼盘项目

Techie并未在其教程中解释如何将导航添加到不同页面。 我一直在想弄清楚该怎么做,但还没有运气。

你们能帮我吗?我已经将我的项目添加到GitHub上了,find the code在那里。

谢谢

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(),
          ],
        ),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

有许多方法可以完成您想要的工作,但是我看到您正在尝试使用Bloc来实现这一目标。这是一个不错的选择,因此您可以在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(),
      ],
    ),
  ),

请记住,Bloc与事件和状态一起使用,因此您可以在CmdNavBloc类中为每个页面添加一个状态,如下所示,并且还可以产生此状态而不是Widget:

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;

      ...
    }
  }
}

接下来,您在菜单抽屉中有一个要填充的每个项目的列表,可以向每个项目添加一个事件以使导航中的事情变得容易,也有很多实现此目的的选项,但这是目前最容易的:

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),
];

最后,您可以按如下所示使用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,
          );
        },

}

enter image description here