Flutter - 提供者
Flutter - Provider
我正在尝试创建以下小部件,在其中按下一个按钮,用户应该被重定向到 MainGameScreen()。
Widget quitGame(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Stack(
children: <Widget>[
Container(
padding:
EdgeInsets.only(left: 20, top: 30, right: 20, bottom: 20),
margin: EdgeInsets.only(top: 45),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black,
offset: Offset(0, 10),
blurRadius: 10),
]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"QUIT GAME",
textScaleFactor: 1,
style: TextStyle(
fontSize: 40, fontWeight: FontWeight.w600),
),
SizedBox(
height: 15,
),
Text(
"Are you sure you want to leave the game?",
textScaleFactor: 1,
style: TextStyle(fontSize: 14),
textAlign: TextAlign.center,
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(0xFFec4688),
),
onPressed: () {
Navigator.of(context).pop();
},
child: Text("NO",
textScaleFactor: 1,
style: TextStyle(fontSize: 20))),
),
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(0xFF1fd281),
),
onPressed: () {
roundTimer.cancel();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MainGameScreen(),
),
);
},
child: Text("YES",
textScaleFactor: 1,
style: TextStyle(fontSize: 20))),
),
],
),
],
),
),
],
),
);
});
}
但是当我这样做时,出现以下错误:
════════ Exception caught by widgets library ═══════════════════════════════════
The following ProviderNotFoundException was thrown building Builder:
Error: Could not find the correct Provider<AuthBloc> above this MainGameScreen Widget
不幸的是,我对提供商不太了解,所以如果有人能解释哪里出了问题以及我该如何解决,我将不胜感激。谢谢
我认为您在 MainGameScreen 中使用了如下代码:
final bloc = Provider.of<AuthBloc>(context, listen: false,);
.
调用此方法时,提供程序包将使用 MainGameScreen 的 context
并查找其上方是否存在类型为 AuthBloc
的 Provider
Widget。如果找不到包,将抛出该异常。
The following ProviderNotFoundException was thrown building Builder:
Error: Could not find the correct Provider<AuthBloc> above this MainGameScreen Widget
所以我认为您应该在 MainGameScreen
小部件上方添加一个类型为 AuthBloc
的 Provider
,它通常如下所示:
Provider<AuthBloc>(
create: (context) => AuthBloc(),
dispose: (context, bloc) => bloc.dispose(), // remove it if there is no dispose method in your BLoC
child: MainGameScreen(),
),
您可以在 MainGameScreen()
上方的任何位置添加此 Provider
并且它还必须具有 AuthBloc
(Provider<AuthBloc>
).
类型
MainGameScreen Widget
必须是 Provider
小部件的后代。但是在这里,您使用 MaterialPageRoute
将新路由推送到您的应用程序,因此 MainGameScreen
将位于小部件树的一个新的独立分支中,它唯一的父级是 Material App Widget
。所以有两种解决方案:
1. Place the ProviderWidget above the MaterialApp Widget. Ex:
Provider<AuthBloc>(
create: (context) => AuthBloc(),
dispose: (context, bloc) => bloc.dispose(), // remove it if there is no dispose method in your BLoC
child: MaterialApp(),
),
2. A trick, which is very useful but really hard to test and manage: Add a `static` method which look like this :
class MainGameScreen extends StatefulWidget {
static Widget create(BuildContext context) {
return Provider<AuthBloc>(
create: (_) => AuthBloc(),
child: MainGameScreen(),
);
}
而当我们使用MaterialPageRoute
推送时,使用:
MaterialPageRoute(
builder: (context) => MainGameScreen.create(context),
),
通过这个解决方案,我们在 MainGameScreen
之上有了一个提供者 ;)。请记住,添加小部件测试非常困难,因此在使用它之前请三思。
对不起我之前愚蠢的解释!
我正在尝试创建以下小部件,在其中按下一个按钮,用户应该被重定向到 MainGameScreen()。
Widget quitGame(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Stack(
children: <Widget>[
Container(
padding:
EdgeInsets.only(left: 20, top: 30, right: 20, bottom: 20),
margin: EdgeInsets.only(top: 45),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black,
offset: Offset(0, 10),
blurRadius: 10),
]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"QUIT GAME",
textScaleFactor: 1,
style: TextStyle(
fontSize: 40, fontWeight: FontWeight.w600),
),
SizedBox(
height: 15,
),
Text(
"Are you sure you want to leave the game?",
textScaleFactor: 1,
style: TextStyle(fontSize: 14),
textAlign: TextAlign.center,
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(0xFFec4688),
),
onPressed: () {
Navigator.of(context).pop();
},
child: Text("NO",
textScaleFactor: 1,
style: TextStyle(fontSize: 20))),
),
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(0xFF1fd281),
),
onPressed: () {
roundTimer.cancel();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MainGameScreen(),
),
);
},
child: Text("YES",
textScaleFactor: 1,
style: TextStyle(fontSize: 20))),
),
],
),
],
),
),
],
),
);
});
}
但是当我这样做时,出现以下错误:
════════ Exception caught by widgets library ═══════════════════════════════════
The following ProviderNotFoundException was thrown building Builder:
Error: Could not find the correct Provider<AuthBloc> above this MainGameScreen Widget
不幸的是,我对提供商不太了解,所以如果有人能解释哪里出了问题以及我该如何解决,我将不胜感激。谢谢
我认为您在 MainGameScreen 中使用了如下代码:
final bloc = Provider.of<AuthBloc>(context, listen: false,);
.
调用此方法时,提供程序包将使用 MainGameScreen 的 context
并查找其上方是否存在类型为 AuthBloc
的 Provider
Widget。如果找不到包,将抛出该异常。
The following ProviderNotFoundException was thrown building Builder:
Error: Could not find the correct Provider<AuthBloc> above this MainGameScreen Widget
所以我认为您应该在 MainGameScreen
小部件上方添加一个类型为 AuthBloc
的 Provider
,它通常如下所示:
Provider<AuthBloc>(
create: (context) => AuthBloc(),
dispose: (context, bloc) => bloc.dispose(), // remove it if there is no dispose method in your BLoC
child: MainGameScreen(),
),
您可以在 MainGameScreen()
上方的任何位置添加此 Provider
并且它还必须具有 AuthBloc
(Provider<AuthBloc>
).
MainGameScreen Widget
必须是 Provider
小部件的后代。但是在这里,您使用 MaterialPageRoute
将新路由推送到您的应用程序,因此 MainGameScreen
将位于小部件树的一个新的独立分支中,它唯一的父级是 Material App Widget
。所以有两种解决方案:
1. Place the ProviderWidget above the MaterialApp Widget. Ex:
Provider<AuthBloc>(
create: (context) => AuthBloc(),
dispose: (context, bloc) => bloc.dispose(), // remove it if there is no dispose method in your BLoC
child: MaterialApp(),
),
2. A trick, which is very useful but really hard to test and manage: Add a `static` method which look like this :
class MainGameScreen extends StatefulWidget {
static Widget create(BuildContext context) {
return Provider<AuthBloc>(
create: (_) => AuthBloc(),
child: MainGameScreen(),
);
}
而当我们使用MaterialPageRoute
推送时,使用:
MaterialPageRoute(
builder: (context) => MainGameScreen.create(context),
),
通过这个解决方案,我们在 MainGameScreen
之上有了一个提供者 ;)。请记住,添加小部件测试非常困难,因此在使用它之前请三思。
对不起我之前愚蠢的解释!