我是Flutter的新手,我还在学习。
的教程创建了一个带有材质驱动侧栏的拼盘项目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(),
],
),
),
);
}
}
答案 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,
);
},
}