Flutter Flatter StreamProvider使用了“BuildContext”,它是该提供程序的祖先
我正在用Flutter开发一个应用程序(我还是个新手),我遇到了以下错误:Flutter Flatter StreamProvider使用了“BuildContext”,它是该提供程序的祖先,flutter,dart,dart-pub,Flutter,Dart,Dart Pub,我正在用Flutter开发一个应用程序(我还是个新手),我遇到了以下错误: Error: Could not find the correct Provider<List<Category>> above this Exercises Widget This likely happens because you used a `BuildContext` that does not include the provider of your choice. There a
Error: Could not find the correct Provider<List<Category>> above this Exercises Widget
This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Exercises is under your MultiProvider/Provider<List<Category>>.
This usually happen when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
错误:在此练习小部件上方找不到正确的提供程序
发生这种情况的原因可能是您使用了不包含提供程序的“BuildContext”
由你选择。有几个常见的场景:
-您试图读取的提供程序位于不同的路径中。
提供者是“有范围的”。所以,如果在路由中插入一个提供者,那么
其他路由将无法访问该提供商。
-您使用了“BuildContext”,它是您试图读取的提供程序的祖先。
确保练习在您的MultiProvider/Provider下进行。
这通常发生在创建提供者并尝试立即读取它时。
例如,而不是:
```
小部件构建(构建上下文){
返回提供者(
创建:()=>Example(),
//将抛出ProviderNotFoundError,因为'context'已关联
//指向作为“提供者”父级的小部件`
子:文本(context.watch()),
),
}
```
考虑使用“Builder”这样:
```
小部件构建(构建上下文){
返回提供者(
创建:()=>Example(),
//我们使用“builder”来获取一个新的“BuildContext”,它可以访问提供者
生成器:(上下文){
//不再投掷
返回文本(context.watch()),
}
),
我一直在网上查看,这显然与我在练习中调用Provider.of(context)时无法获得正确的“context”有关,我不太明白为什么。因为正如你在我的练习中所看到的。dart我有“body:ExerciseList(),在其中我可以从StreamProvider获取类别,但当我试图通过单击“floatingActionButton”访问它,然后尝试打开我的ExerciseAdd()页面时,它会抛出该错误
如果能提供一个解决方案(+解释),说明如何修复我的代码以及为什么代码不起作用,我将不胜感激
练习。飞镖
Widget build(BuildContext context) {
return _isLoading
? Loading()
: MultiProvider(
providers: [
StreamProvider<List<Exercise>>(
create: (context) => DatabaseService().exercises,
),
StreamProvider<List<Category>>(
create: (context) => DatabaseService().categories,
),
ChangeNotifierProvider<ExerciseFilter>(
create: (context) => ExerciseFilter(isActive: true),
)
],
child: Scaffold(
appBar: AppBar(
title: Text('Exercises'),
elevation: 0.0,
actions: _buildActions(),
),
body: ExerciseList(),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExercisesAdd(),
),
);
},
),
),
);
}
}
@override
Widget build(BuildContext context) {
final cats = Provider.of<List<Category>>(context);
print(cats.length);
return Scaffold(
appBar: AppBar(
title: Text('Add Exercise'),
elevation: 0.0,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration:
textInputDecoration.copyWith(hintText: 'Exercise Name'),
validator: (value) {
if (value.isEmpty) {
return 'Exercise name is required';
}
return null;
},
onChanged: (value) {
setState(() {
exerciseName = value;
});
},
),
SizedBox(height: 20.0),
Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.white),
child: DropdownButtonFormField<String>(
decoration: dropdownDecoration,
value: exerciseCategory,
onChanged: (value) {
setState(() {
exerciseCategory = value;
});
},
items: categories.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value.name,
child: Text(value.name),
);
}).toList(),
),
),
SizedBox(height: 20.0),
RaisedButton(
elevation: 0,
color: Colors.black,
child: Text(
'Add Exercise',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
bool failed = false;
String uid = await _auth.getCurrentUser();
if (uid != null) {
dynamic result = DatabaseService(uid: uid)
.addExercise(exerciseName, exerciseCategory);
if (result != null) {
Navigator.pop(context);
} else {
failed = true;
}
} else {
failed = true;
}
if (failed) {
setState(() {
error = 'Failed to add exercise. Please try again';
});
}
}
},
),
SizedBox(height: 12.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 14.0),
),
],
),
),
),
),
);
小部件构建(构建上下文){
返回-卸载
?加载()
:多供应商(
供应商:[
流提供者(
创建:(上下文)=>DatabaseService()。练习,
),
流提供者(
创建:(上下文)=>DatabaseService()。类别,
),
变更通知提供者(
create:(context)=>ExerciseFilter(isActive:true),
)
],
孩子:脚手架(
appBar:appBar(
标题:文本(“练习”),
标高:0.0,
操作:_buildActions(),
),
正文:ExerciseList(),
浮动操作按钮:浮动操作按钮(
背景颜色:Colors.black,
子项:图标(Icons.add,颜色:Colors.white),
已按下:(){
导航器。推(
上下文
材料路线(
生成器:(上下文)=>exercisedd(),
),
);
},
),
),
);
}
}
练习\u添加省道
Widget build(BuildContext context) {
return _isLoading
? Loading()
: MultiProvider(
providers: [
StreamProvider<List<Exercise>>(
create: (context) => DatabaseService().exercises,
),
StreamProvider<List<Category>>(
create: (context) => DatabaseService().categories,
),
ChangeNotifierProvider<ExerciseFilter>(
create: (context) => ExerciseFilter(isActive: true),
)
],
child: Scaffold(
appBar: AppBar(
title: Text('Exercises'),
elevation: 0.0,
actions: _buildActions(),
),
body: ExerciseList(),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExercisesAdd(),
),
);
},
),
),
);
}
}
@override
Widget build(BuildContext context) {
final cats = Provider.of<List<Category>>(context);
print(cats.length);
return Scaffold(
appBar: AppBar(
title: Text('Add Exercise'),
elevation: 0.0,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration:
textInputDecoration.copyWith(hintText: 'Exercise Name'),
validator: (value) {
if (value.isEmpty) {
return 'Exercise name is required';
}
return null;
},
onChanged: (value) {
setState(() {
exerciseName = value;
});
},
),
SizedBox(height: 20.0),
Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.white),
child: DropdownButtonFormField<String>(
decoration: dropdownDecoration,
value: exerciseCategory,
onChanged: (value) {
setState(() {
exerciseCategory = value;
});
},
items: categories.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value.name,
child: Text(value.name),
);
}).toList(),
),
),
SizedBox(height: 20.0),
RaisedButton(
elevation: 0,
color: Colors.black,
child: Text(
'Add Exercise',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
bool failed = false;
String uid = await _auth.getCurrentUser();
if (uid != null) {
dynamic result = DatabaseService(uid: uid)
.addExercise(exerciseName, exerciseCategory);
if (result != null) {
Navigator.pop(context);
} else {
failed = true;
}
} else {
failed = true;
}
if (failed) {
setState(() {
error = 'Failed to add exercise. Please try again';
});
}
}
},
),
SizedBox(height: 12.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 14.0),
),
],
),
),
),
),
);
@覆盖
小部件构建(构建上下文){
最终猫=提供者(上下文);
印刷品(猫的长度);
返回脚手架(
appBar:appBar(
标题:文本(“添加练习”),
标高:0.0,
),
正文:SingleChildScrollView(
子:容器(
填充:边缘组。对称(垂直:20.0,水平:50.0),
孩子:表格(
键:_formKey,
子:列(
儿童:[
尺寸箱(高度:20.0),
TextFormField(
装饰:
textInputDecoration.copyWith(hintText:“练习名”),
验证器:(值){
if(value.isEmpty){
返回“需要练习名称”;
}
返回null;
},
一旦更改:(值){
设置状态(){
exerciseName=值;
});
},
),
尺寸箱(高度:20.0),
主题(
数据:Theme.of(context).copyWith(canvasColor:Colors.white),
子项:DropdownButtonFormField(
装饰:下拉装饰,
值:exerciseCategory,
一旦更改:(值){
设置状态(){
锻炼类别=价值;
});
},
项:categories.map((值){
返回下拉菜单项(
value:value.name,
子项:文本(value.name),
);
}).toList(),
),
),
尺寸箱(高度:20.0),
升起的按钮(
海拔:0,
颜色:颜色,黑色,
子:文本(
“添加练习”,
样式:TextStyle(颜色:Colors.white),
),
onPressed:()异步{
if(_formKey.currentState.validate()){
bool失败=错误;
字符串uid=await_auth.getCurrentUser();
如果(uid!=null){
动态结果=数据库服务(uid:uid)
.附录练习(练习名称、练习类别);
如果(结果!=null){
Navigator.pop(上下文);
}否则{
F