我想在小部件上实时获取来自Firebase的数据。当我尝试使用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
。
这里是repository。
答案 0 :(得分:1)
我想出了办法。我使用了一个名为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()
来获取数据。