flutter - 使用命名路由导航时找不到流提供程序
问题描述
我有一个不工作的流提供程序(连接到 firebase)。我猜问题在于我使用的是命名导航器 [Navigator.pushNamed(context, '/route',)]。我想这使得“路线”小部件不是调用它的小部件的儿子。让我在下面更好地展示它。
我的应用程序结构如下:我的主要小部件处理路由并通过用户身份验证接收流(这里没有问题):
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthService().user,
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Wrapper(),
routes: {
'/home': (context) => Wrapper(),
'/edit_profile': (context) => UserProfile() //This is where I am having trouble.
}
),
);
}
}
验证用户是否已通过身份验证并采取相应措施的Wrapper :
class Wrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
// return either the Home or Authenticate widget
if (user == null){
return Authenticate();
} else {
return HomeWrapper();
}
}
}
HomeWrapper接收第二个流并重定向到我遇到问题的小部件:
class HomeWrapper extends StatefulWidget {
@override
_HomeWrapperState createState() => _HomeWrapperState();
}
class _HomeWrapperState extends State<HomeWrapper> {
String currentBodyName = 'home';
Widget currentBodyWidget = Home();
@override
Widget build(BuildContext context) {
Widget _drawerOptions = Row(
children: [
FlatButton(child: someChild, onPressed: () {Navigator.pushNamed(context, '/edit_profile',);},), //This is the actual call to the navigator.
],
);
return StreamProvider<Map>.value( //This is the problematic Stream!
value: DatabaseService().userDetail,
child: Scaffold(
//Body
body: currentBodyWidget,
//I am simplifying this to show the most important parts
bottomNavigationBar: myBottomNavigationBar(
buttons: <Widget>[
FlatButton(
icon: someIcon,
onPressed: () => _onItemTapped('home'),
),
FlatButton(
icon: otherIcon,
onPressed: () => _onItemTapped('second_screen'),
),
],)
//Drawer
drawer: Drawer(child: _drawerOptions,), //This one has the call to the problematic edit_profile route.
);
}
void _onItemTapped(String newBodyName) {
if (newBodyName != currentBodyName){
setState(() {
currentBodyName = newBodyName;
switch(newBodyName) {
case 'home': {
currentBodyWidget = Home();
}
break;
case 'second_screen': {
currentBodyWidget = SecondScreen();
}
break;
default: {
currentBodyWidget = Home();
}
break;
}
});
}
}
}
最后,edit_profile路由调用UserProfile小部件,如下所示:
class UserProfile extends StatefulWidget {
@override
_UserProfileState createState() => _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
@override
Widget build(BuildContext context) {
//This is where the error occurs!!
final userDocument = Provider.of<Map>(context) ?? [];
print(userDocument);
return Scaffold(body: Container());
}
}
这是它抛出的错误:
The following ProviderNotFoundError was thrown building UserProfile(dirty, state: _UserProfileState#09125):
Error: Could not find the correct Provider<Map<dynamic, dynamic>> above this UserProfile Widget
非常感谢!!
解决方案
原来我的方法是错误的。
我没有用 StreamProvider 包装 HomeWrapper,而是希望它将数据传递到下一个路由(UserProfile),我所做的是用 StreamProvider 包装 UserProfile 小部件,如下所示:
(注意:我将 Map StreamProvider 更改为 UserData StreamProvider。)
class UserProfile extends StatefulWidget {
@override
_UserProfileState createState() => _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
return Scaffold(
body: Container(
//My Widget here
);
} else
return Loading();
});
}
}
这个系列非常有帮助:https ://www.youtube.com/playlist?list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC
推荐阅读
- dsl - 使用“==”和“包含”使用通用脚本进行空手道比赛的最佳方法
- java - 如何在 PDF 中正确显示 Jasper 报告导出的越南语?
- c# - 将派生类型的集合作为基类型的集合访问
- regex - 重复的任意捕获组
- excel - 工作表中多个数据范围的第一行和最后一行/第一列和最后一列
- sql - 访问,使用 VBA 自动匹配 2 个记录集之间的记录
- django - Django,在views.py中使用视图集
- java - 如何在缓存的分页结果中添加新对象或更新对象
- reactjs - 使用直接链接访问路由不显示道具 Reactjs?
- swift - 获取 shell 命令的 7zip 等实用程序的完整路径