我想在小部件上实时获取来自Firebase的数据。当我尝试使用a StreamProvider然后使用时Navigator.push(),推送的小部件无法使用来获取值Provider.of(context)。
StreamProvider
Navigator.push()
Provider.of(context)
我尝试将设置StreamProvider为的父项MaterialApp。这可行,但是需要登录用户才能使Stream获得用户的数据。我也尝试使用ScopedModel。这也可以,但是我不知道这是否是最好的方法。
MaterialApp
ScopedModel
我想避免使用全局方法StreamProvider,而是希望有一个有效的解决方案(尽可能少地读取Firebase)
main.dart
void main() => runApp(MyApp()); final GlobalKey<ScaffoldState> mainScaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> authScaffoldKey = GlobalKey<ScaffoldState>(); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ScopedModel<ScreenModel>( model: ScreenModel(), child: MultiProvider( providers: [ StreamProvider<User>.value(value: authService.userDoc,), StreamProvider<bool>.value(value: authService.loading.asBroadcastStream()) ], child: MaterialApp( title: "ListAssist", theme: ThemeData( primarySwatch: Colors.indigo, ), home: MainApp() ), ) ); } } class MainApp extends StatefulWidget { @override _MainAppState createState() => _MainAppState(); } class _MainAppState extends State<MainApp> { @override Widget build(BuildContext context) { User user = Provider.of<User>(context); bool loading = Provider.of<bool>(context); return AnimatedSwitcher( duration: Duration(milliseconds: 600), child: user != null ? StreamProvider<Group>.value( value: databaseService.streamGroupsFromUser(), child: Scaffold( key: mainScaffoldKey, body: Body(), drawer: Sidebar(), ), ) : Scaffold( key: authScaffoldKey, body: AnimatedSwitcher( duration: Duration(milliseconds: 600), child: loading ? SpinKitDoubleBounce(color: Colors.blueAccent) : AuthenticationPage(), ), resizeToAvoidBottomInset: false, ) ); } } class Body extends StatefulWidget { createState() => _Body(); } class _Body extends State<Body> { @override Widget build(BuildContext context) { return ScopedModelDescendant<ScreenModel>( builder: (context, child, model) => model.screen ); } }
在补充工具栏中,我可以更改为GroupView,并且Provider仍然可以使用。
GroupView
Provider
sidebar.dart (重要部分)
sidebar.dart
onTap: () { ScreenModel.of(context).setScreen(GroupView(), "Gruppen"); Navigator.pop(context); },
在GroupView拥有GroupItem它
GroupItem
group-item.dart (重要部分)
group-item.dart
onTap: () => Navigator.push( context, MaterialPageRoute(builder: (context) { return GroupDetail(); }), )
当我尝试使用Group group = Provider.of<Group>(context);中GroupDetail或它的子窗口部件,它说,它无法找到任何Provider的context。
Group group = Provider.of<Group>(context);
GroupDetail
context
这是存储库。
我想出了办法。我使用了一个名为的软件包custom_navigator。
custom_navigator
在sidebar.dart我改变了孩子,当有人要改变该组查看以下内容:
StreamProvider<Group>.value( value: databaseService.streamGroupsFromUser(user.uid), child: CustomNavigator( home: GroupView(), pageRoute: PageRoutes.materialPageRoute, ) )
有了,即使在之后,CustomNavigator我仍然可以Provider.of<Group>(context)用来获取数据Navigator.push()。
CustomNavigator
Provider.of<Group>(context)