如何通过不同的页面(上下文)共享来自streambuilder的提供者数据
问题内容:
我想在小部件上实时获取来自Firebase的数据。当我尝试使用a
StreamProvider
然后使用时Navigator.push()
,推送的小部件无法使用来获取值Provider.of(context)
。
我尝试将设置StreamProvider
为的父项MaterialApp
。这可行,但是需要登录用户才能使Stream获得用户的数据。我也尝试使用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
仍然可以使用。
sidebar.dart
(重要部分)
onTap: () {
ScreenModel.of(context).setScreen(GroupView(), "Gruppen");
Navigator.pop(context);
},
在GroupView
拥有GroupItem
它
group-item.dart
(重要部分)
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return GroupDetail();
}),
)
当我尝试使用Group group = Provider.of<Group>(context);
中GroupDetail
或它的子窗口部件,它说,它无法找到任何Provider
的context
。
这是存储库。
问题答案:
我想出了办法。我使用了一个名为的软件包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()
。