如何在 Bloc Login Flutter 中使用带有身份验证的 NavigationDrawer 路由
Posted
技术标签:
【中文标题】如何在 Bloc Login Flutter 中使用带有身份验证的 NavigationDrawer 路由【英文标题】:How to use routes in Bloc Login Flutter for NavigationDrawer with authentication 【发布时间】:2020-05-22 10:24:13 【问题描述】:我实现了 Flutter Bloc Login 示例,与指南页面 here 完全一样:
接下来,我在页面中添加了 NavigationDrawer。
但我不知道如何跨页面导航,我尝试了正常的 Navigator.push 但不起作用,我在 MaterialApp 中使用了 routes 不幸的是不是那样工作的。
main.dart
void main()
BlocSupervisor.delegate = SimpleBlocDelegate();
final userRepository = UserRepository();
runApp(
BlocProvider<AuthenticationBloc>(
create: (context)
return AuthenticationBloc(userRepository: userRepository)
..add(AppStarted());
,
child: App(userRepository: userRepository),
),
);
class App extends StatelessWidget
final UserRepository userRepository;
App(Key key, @required this.userRepository) : super(key: key);
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state)
if (state is AuthenticationAuthenticated)
//return Counter();
//return ListPage();
return ProfilePage();
if (state is AuthenticationUnauthenticated)
return LoginPage(userRepository: userRepository);
if (state is AuthenticationLoading)
return LoadingIndicator();
return SplashPage();
,
),
initialRoute: '/',
routes:
'/': (context) => SplashPage(),
'/counter': (context) => Counter(),
'/profile': (context) => ProfilePage(),
'/list': (context) => ListPage(),
,
);
navigation_drawer.dart
Widget build(BuildContext context)
return Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
Container(...),
ListTile(
title: Text('Profile'),
onTap: ()
/* TODO: check token is not null */
Navigator.pushNamed(context, '/profile');
,
),
ListTile(
title: Text('Counter'),
onTap: ()
Navigator.pushNamed(context, '/counter');
,
),
ListTile(
title: Text('My List'),
onTap: ()
Navigator.pushNamed(context, '/list');
,
),
],
),
);
【问题讨论】:
【参考方案1】:这很简单,您忘记使用 Scaffold 小部件作为 Material 小部件的子小部件,而 Scaffold 有一个属性抽屉,您可以将抽屉传递给它。如下:
main.dart
void main()
BlocSupervisor.delegate = SimpleBlocDelegate();
final userRepository = UserRepository();
runApp(
BlocProvider<AuthenticationBloc>(
create: (context)
return AuthenticationBloc(userRepository: userRepository)
..add(AppStarted());
,
child: App(userRepository: userRepository),
),
);
class App extends StatelessWidget
final UserRepository userRepository;
App(Key key, @required this.userRepository) : super(key: key);
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
drawer: build(context),
body: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state)
if (state is AuthenticationAuthenticated)
//return Counter();
//return ListPage();
return ProfilePage();
if (state is AuthenticationUnauthenticated)
return LoginPage(userRepository: userRepository);
if (state is AuthenticationLoading)
return LoadingIndicator();
return SplashPage();
,
),
),
initialRoute: '/',
routes:
'/': (context) => SplashPage(),
'/counter': (context) => Counter(),
'/profile': (context) => ProfilePage(),
'/list': (context) => ListPage(),
,
);
navigation_drawer.dart
Widget build(BuildContext context)
return Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
Container(...),
ListTile(
title: Text('Profile'),
onTap: ()
/* TODO: check token is not null */
Navigator.pushNamed(context, '/profile');
,
),
ListTile(
title: Text('Counter'),
onTap: ()
Navigator.pushNamed(context, '/counter');
,
),
ListTile(
title: Text('My List'),
onTap: ()
Navigator.pushNamed(context, '/list');
,
),
],
),
);
但我不建议你以这种方式使用 bloc。
【讨论】:
以上是关于如何在 Bloc Login Flutter 中使用带有身份验证的 NavigationDrawer 路由的主要内容,如果未能解决你的问题,请参考以下文章