在使用Bloc侦听器时,我会遇到一个错误ProvidNotFoundException(错误:找不到正确的提供商< todosbloc>
我正在学习集团,正在制作一个todo应用程序,但是在打电话给我的集团听众时,除了做屏幕之外,它还会出现错误。 错误在添加待办事项类别中显示
例外发生了。 providernotfoundException(错误:无法在此bloclistener< todosbloc,todosstate> widt部门上方找到正确的
提供商 您的选择。有几种常见的情况:
您在
main.dart
中添加了一个新的提供商,并执行了热线功能。 要修复,请执行热点。您要阅读的提供商是在不同的路线中。
提供商“范围”。因此,如果您将提供商插入路线中,则 其他路线将无法访问该提供商。
您使用了
buildContext
,它是您要阅读的提供者的祖先。
确保bloclistener< todosbloc,todosstate>位于您的多个工业/提供商之下。 通常,当您创建提供商并试图立即阅读它时,这通常会发生。
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>().toString()),
);
}
```
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, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
```
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
)
这是我的代码...
main.dart
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'home_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff000A1F),
appBarTheme: AppBarTheme(
color: Color(0xff000A1F),
),
),
home: MultiBlocProvider(providers: [
BlocProvider(
create: (context) => TodosBloc()
..add(
LoadTodo(
todos: [
Todo(
id: '1',
task: 'Sample Todo 1',
description: 'This is a test Todo',
),
Todo(
id: '2',
task: 'Sample Todo 2',
description: 'This is a test Todo',
),
],
),
),
)
], child: HomeScreen()),
);
}
}
homescreen.dart
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'add_todo_screen.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<TodosBloc, TodosState>(
builder: (context, state) {
if (state is TodosLoading) {
return CircularProgressIndicator();
}
if (state is TodosLoaded) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc Pattern To Dos'),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddToDo(),
),
);
},
icon: Icon(
Icons.add,
color: Colors.white,
),
),
],
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Text(
'Pending To Dos..',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
ListView.builder(
shrinkWrap: true,
itemCount: state.todos.length,
itemBuilder: (context, index) {
return _todoCard(state.todos[index]);
})
]),
),
);
} else {
return Text('Something Went Wrong');
}
},
);
}
}
Card _todoCard(Todo todo) {
return Card(
margin: EdgeInsets.only(bottom: 8.0, top: 8),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'#${todo.id}: ${todo.task}',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.add_task,
),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.cancel,
),
),
],
)
],
),
),
);
}
添加到做屏幕。
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AddToDo extends StatelessWidget {
TextEditingController controllerId = TextEditingController();
TextEditingController controllerTask = TextEditingController();
TextEditingController controllerDescription = TextEditingController();
AddToDo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Dos'),
),
body: BlocListener<TodosBloc, TodosState>(
listener: (context, state) {
if (state is TodosLoaded) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("To Do Added Successfuly"),
),
);
}
},
child: Card(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
_inputField('ID', controllerId),
_inputField('Task', controllerTask),
_inputField('Description', controllerDescription),
Builder(builder: (context) {
return ElevatedButton(
onPressed: () {
var todo = Todo(
id: controllerId.text,
task: controllerTask.text,
description: controllerDescription.text,
);
context.read<TodosBloc>().add(AddTodo(todo: todo));
},
child: Text('Add Todo'),
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
);
}),
],
),
),
),
),
);
}
}
_inputField(String label, TextEditingController controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${label}:',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
height: 50,
margin: EdgeInsets.only(
bottom: 10,
),
width: double.infinity,
child: TextFormField(
controller: controller,
),
)
],
);
}
I am learning bloc and was making a todo app but while calling my bloc listener in addition to do screen it is throwing an error. Error is showing in Add To-Do Class
The exception has occurred.
ProviderNotFoundException (Error: Could not find the correct Provider above this BlocListener<TodosBloc, TodosState> Widget
This happens because you used a BuildContext
that does not include the provider
of your choice. There are a few common scenarios:
You added a new provider in your
main.dart
and performed a hot-reload.
To fix, perform a hot-restart.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 BlocListener<TodosBloc, TodosState> is under your MultiProvider/Provider.
This usually happens 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>().toString()),
);
}
```
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, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
```
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
)
Here is my code...
Main.dart
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'home_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff000A1F),
appBarTheme: AppBarTheme(
color: Color(0xff000A1F),
),
),
home: MultiBlocProvider(providers: [
BlocProvider(
create: (context) => TodosBloc()
..add(
LoadTodo(
todos: [
Todo(
id: '1',
task: 'Sample Todo 1',
description: 'This is a test Todo',
),
Todo(
id: '2',
task: 'Sample Todo 2',
description: 'This is a test Todo',
),
],
),
),
)
], child: HomeScreen()),
);
}
}
HomeScreen.Dart
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'add_todo_screen.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<TodosBloc, TodosState>(
builder: (context, state) {
if (state is TodosLoading) {
return CircularProgressIndicator();
}
if (state is TodosLoaded) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc Pattern To Dos'),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddToDo(),
),
);
},
icon: Icon(
Icons.add,
color: Colors.white,
),
),
],
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Text(
'Pending To Dos..',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
ListView.builder(
shrinkWrap: true,
itemCount: state.todos.length,
itemBuilder: (context, index) {
return _todoCard(state.todos[index]);
})
]),
),
);
} else {
return Text('Something Went Wrong');
}
},
);
}
}
Card _todoCard(Todo todo) {
return Card(
margin: EdgeInsets.only(bottom: 8.0, top: 8),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'#${todo.id}: ${todo.task}',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.add_task,
),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.cancel,
),
),
],
)
],
),
),
);
}
Add To Do Screen.Dart
import 'package:bloc_practise/blocs/todos/todos_bloc.dart';
import 'package:bloc_practise/todo_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AddToDo extends StatelessWidget {
TextEditingController controllerId = TextEditingController();
TextEditingController controllerTask = TextEditingController();
TextEditingController controllerDescription = TextEditingController();
AddToDo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Dos'),
),
body: BlocListener<TodosBloc, TodosState>(
listener: (context, state) {
if (state is TodosLoaded) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("To Do Added Successfuly"),
),
);
}
},
child: Card(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
_inputField('ID', controllerId),
_inputField('Task', controllerTask),
_inputField('Description', controllerDescription),
Builder(builder: (context) {
return ElevatedButton(
onPressed: () {
var todo = Todo(
id: controllerId.text,
task: controllerTask.text,
description: controllerDescription.text,
);
context.read<TodosBloc>().add(AddTodo(todo: todo));
},
child: Text('Add Todo'),
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
);
}),
],
),
),
),
),
);
}
}
_inputField(String label, TextEditingController controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${label}:',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
height: 50,
margin: EdgeInsets.only(
bottom: 10,
),
width: double.infinity,
child: TextFormField(
controller: controller,
),
)
],
);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您打算在多个页面上使用集团,则必须将其放在
材料App
小部件上方,这是因为每个页面都是yeartialpage
的孩子,请花一点时间阅读您的错误消息:因此,而不是
这样做:
If you intend to use a bloc on multiple pages, you must put it above the
MaterialApp
widget, this is because every page is a child of theMaterialPage
, please take a moment to read your error message:So instead of having
do this: