错误状态:试图读取在创建其值期间抛出的提供者。创建 HomeBloc 类型时出现异常
Bad state: Tried to read a provider that threw during the creation of its value. The exception occurred during the creation of type HomeBloc
我在我的主文件中添加了多个块并为每个屏幕使用 1 个块,但是当我转到下一个屏幕并返回到上一个屏幕然后再次尝试触发事件时它给出了第二个块状态错误的错误.
主要class
void main() {
runApp(MultiBlocProvider(
providers:[
BlocProvider<LoginBloc>(
create:(_) => LoginBloc(),
),
BlocProvider<HomeBloc>(
create: (_) => HomeBloc()
),
BlocProvider<UnitBloc>(
create: (_) => UnitBloc()
),
],
child: MyApp()
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Watchman',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: MyColors.primaryTheme,
bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.transparent)
// scaffoldBackgroundColor: MyColors.colorBGBrown
),
home: LoginPage(),
);
}
}
登录屏幕
class LoginPage extends StatefulWidget {
LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final userController = TextEditingController();
final pswdController = TextEditingController();
String userName = '';
String password = '';
@override
void dispose() {
// TODO: implement dispose
userController.dispose();
pswdController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LoginBloc(),
child: BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state is LoginSuccessState) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
} else if (state is LoginErrorState) {
showInSnackBar(context, state.error);
}
},
child: Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: BlocBuilder<LoginBloc, LoginState>(
builder: (context, state) {
if (state is LoginLoadingState) {
return const Center(
child: CircularProgressIndicator()
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image.asset(
'Assets/iclogo.png',
),
SizedBox(height: 40),
Container(
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: TextFormFieldWidget(
labelText: 'UserName',
controller: userController,
),
),
Container(
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: TextFormFieldWidget(
labelText: 'Password',
isPassword: true,
controller: pswdController,
),
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: ElevatedButtonWidget(
onPressed: () {
userName = userController.text;
password = pswdController.text;
context.read<LoginBloc>().add(
LoginEventSubmit(
username: userName,
password: password)
);
},
text: 'Login',
bgColor: MyColors.colorPrimary,
textColor: Colors.white,
),
),
],
);
}
},
),
),
),
);
}
void showInSnackBar(BuildContext context, String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
// duration: Duration(seconds: 2),
),
);
}
}
login_bloc
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<LoginEvent>((event, emit) async {
// TODO: implement event handler
if(event is LoginEventSubmit){
if(event.username.isEmpty || event.password.isEmpty){
emit(LoginErrorState("Please Enter all Fields"));
}else{
emit(LoginLoadingState());
try{
print(event.username +".."+ event.password);
final LoginModel user = await login(event.username ,event.password);
if(user.result=="200"){
emit(LoginSuccessState(user));
}else {
emit(LoginErrorState("UserName or Password is wrong"));
}
}catch (e){
print("error..."+e.toString());
emit(LoginErrorState("Login Failed"));
}
}
}
});
}
Future<LoginModel> login(String username, String pwd) async {
final Dio _dio = Dio();
final queryParameters = {
'username': username,
'pswd':pwd,
};
final response = await _dio.post(AppConstants.login,queryParameters: queryParameters);
final jsonResponse =response.data;
print(jsonResponse.toString());
return LoginModel.fromJson(jsonResponse);
}
}
主屏幕
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Initial Selected Value
@override
void initState() {
// TODO: implement initState
super.initState();
}
Development _selected = Development(
dEVNAME: "Select Building",
dEVCODE: "0"
);
// List of items in our dropdown menu
List<Development>? devList ;
@override
Widget build(BuildContext context) {
return BlocProvider<HomeBloc>(
create: (context) => BlocProvider.of<HomeBloc>(context)..add(GetDevEvent()),
child: BlocListener<HomeBloc, HomeState>(
listener: (context, state) {
// TODO: implement listener
if(state is HomeInitial){
}else if (state is HomeErrorState){
showInSnackBar(context, state.error);
}else if(state is HomeLoadedState){
// devList?.addAll(state.devList);
devList= state.devList;
devList?.add(_selected);
}else if(state is HomeSelectedState){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnitsPage(
devCode: state.devCode,
devName: state.devName,
)
)
);
}
},
child: Scaffold(
appBar: AppBar(
title: const Text("Home"),
),
body: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
if (state is HomeLoadingState) {
return const Center(
child: CircularProgressIndicator()
);
} else {
return Center(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(color: MyColors.colorBlack),
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton<Development>(
// Initial Value
value: _selected,
isExpanded: true,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
iconSize: 25,
// Array list of items
items: devList?.map<DropdownMenuItem<Development>>((Development value) {
return DropdownMenuItem<Development>(
value: value,
child: Text(value.dEVNAME!),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (newVal) => setState(() => _selected = newVal!),
)
),
SizedBox(
height: 20,
),
Container(
width: double.infinity,
padding:
EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: ElevatedButtonWidget(
onPressed: () {
if(_selected.dEVCODE!="0"){
BlocProvider.of<HomeBloc>(context).add(
DevSelectEvent(
devCode:_selected.dEVCODE,
devName: _selected.dEVNAME,
)
);
}else{
String msg = "please "+_selected.dEVNAME!;
showInSnackBar(context, msg);
}
},
text: 'Search',
),
)
],
),
),
);
}
},
),
),
),
);
}
void showInSnackBar(BuildContext context, String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
// duration: Duration(seconds: 2),
),
);
}
}
主场
class HomeBloc extends Bloc<HomeEvent, HomeState> {
HomeBloc() : super(HomeInitial()) {
on<HomeEvent>((event, emit) async {
// TODO: implement event handler
if(event is GetDevEvent){
emit(HomeLoadingState());
try{
DevData devList = await getData();
if(devList.result =="1"){
emit(HomeLoadedState(devList.development));
print("data.."+ devList.toString());
}else{
emit(HomeErrorState("No data Found"));
}
}catch (e){
print("error..."+e.toString());
emit(HomeErrorState("Failed"));
}
}
if(event is DevSelectEvent){
emit(HomeLoadingState());
emit(HomeSelectedState(event.devName!,event.devCode!));
}
});
}
Future<DevData> getData() async {
final Dio _dio = Dio();
final response = await _dio.post(AppConstants.getDevs);
final jsonResponse =response.data;
print(jsonResponse.toString());
return DevData.fromJson(jsonResponse);
}
}
错误日志:
Bad state: Tried to read a provider that threw during the creation of its value.
The exception occurred during the creation of type HomeBloc.
══╡ EXCEPTION CAUGHT BY PROVIDER ╞═══════════════════════════════
The following StateError was thrown:
Bad state: Cannot add new events after calling close
When the exception was thrown, this was the stack:
#1 Bloc.add (package:bloc/src/bloc.dart:84:24)
#2 _HomePageState.build.<anonymous closure> (package:watchman/Home/HomePage.dart:39:64)
#3 _CreateInheritedProviderState.value (package:provider/src/inherited_provider.dart:729:36)
#4 _InheritedProviderScopeElement.value (package:provider/src/inherited_provider.dart:583:33)
#5 Provider.of (package:provider/src/provider.dart:303:37)
#6 ReadContext.read (package:provider/src/provider.dart:656:21)
#7 _BlocListenerBaseState.initState (package:flutter_bloc/src/bloc_listener.dart:147:36)
#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4942:57)
#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#10 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
#11 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#12 Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
#13 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4832:16)
#14 _InheritedProviderScopeElement.performRebuild (package:provider/src/inherited_provider.dart:495:11)
#15 Element.rebuild (package:flutter/src/widgets/framework.dart:4529:5)
#16 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4787:5)
#17 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#18 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:395:11)
... Normal element mounting (7 frames)
#25 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (7 frames)
#32 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (283 frames)
#315 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#316 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6350:36)
#317 Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
#318 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5883:32)
#319 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6375:17)
#320 Element.updateChild (package:flutter/src/widgets/framework.dart:3530:15)
#321 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4832:16)
#322 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4977:11)
我通过在 initstate() 中添加我的第一个事件而不是 BlocProvder 来解决这个问题。
late HomeBloc bloc;
// Initial Selected Value
@override
void initState() {
// TODO: implement initState
bloc = HomeBloc();
bloc.add(GetDevEvent());
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
bloc.close();
super.dispose();
}
我在我的主文件中添加了多个块并为每个屏幕使用 1 个块,但是当我转到下一个屏幕并返回到上一个屏幕然后再次尝试触发事件时它给出了第二个块状态错误的错误.
主要class
void main() {
runApp(MultiBlocProvider(
providers:[
BlocProvider<LoginBloc>(
create:(_) => LoginBloc(),
),
BlocProvider<HomeBloc>(
create: (_) => HomeBloc()
),
BlocProvider<UnitBloc>(
create: (_) => UnitBloc()
),
],
child: MyApp()
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Watchman',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: MyColors.primaryTheme,
bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.transparent)
// scaffoldBackgroundColor: MyColors.colorBGBrown
),
home: LoginPage(),
);
}
}
登录屏幕
class LoginPage extends StatefulWidget {
LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final userController = TextEditingController();
final pswdController = TextEditingController();
String userName = '';
String password = '';
@override
void dispose() {
// TODO: implement dispose
userController.dispose();
pswdController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LoginBloc(),
child: BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state is LoginSuccessState) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
} else if (state is LoginErrorState) {
showInSnackBar(context, state.error);
}
},
child: Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: BlocBuilder<LoginBloc, LoginState>(
builder: (context, state) {
if (state is LoginLoadingState) {
return const Center(
child: CircularProgressIndicator()
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image.asset(
'Assets/iclogo.png',
),
SizedBox(height: 40),
Container(
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: TextFormFieldWidget(
labelText: 'UserName',
controller: userController,
),
),
Container(
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: TextFormFieldWidget(
labelText: 'Password',
isPassword: true,
controller: pswdController,
),
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
child: ElevatedButtonWidget(
onPressed: () {
userName = userController.text;
password = pswdController.text;
context.read<LoginBloc>().add(
LoginEventSubmit(
username: userName,
password: password)
);
},
text: 'Login',
bgColor: MyColors.colorPrimary,
textColor: Colors.white,
),
),
],
);
}
},
),
),
),
);
}
void showInSnackBar(BuildContext context, String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
// duration: Duration(seconds: 2),
),
);
}
}
login_bloc
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<LoginEvent>((event, emit) async {
// TODO: implement event handler
if(event is LoginEventSubmit){
if(event.username.isEmpty || event.password.isEmpty){
emit(LoginErrorState("Please Enter all Fields"));
}else{
emit(LoginLoadingState());
try{
print(event.username +".."+ event.password);
final LoginModel user = await login(event.username ,event.password);
if(user.result=="200"){
emit(LoginSuccessState(user));
}else {
emit(LoginErrorState("UserName or Password is wrong"));
}
}catch (e){
print("error..."+e.toString());
emit(LoginErrorState("Login Failed"));
}
}
}
});
}
Future<LoginModel> login(String username, String pwd) async {
final Dio _dio = Dio();
final queryParameters = {
'username': username,
'pswd':pwd,
};
final response = await _dio.post(AppConstants.login,queryParameters: queryParameters);
final jsonResponse =response.data;
print(jsonResponse.toString());
return LoginModel.fromJson(jsonResponse);
}
}
主屏幕
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Initial Selected Value
@override
void initState() {
// TODO: implement initState
super.initState();
}
Development _selected = Development(
dEVNAME: "Select Building",
dEVCODE: "0"
);
// List of items in our dropdown menu
List<Development>? devList ;
@override
Widget build(BuildContext context) {
return BlocProvider<HomeBloc>(
create: (context) => BlocProvider.of<HomeBloc>(context)..add(GetDevEvent()),
child: BlocListener<HomeBloc, HomeState>(
listener: (context, state) {
// TODO: implement listener
if(state is HomeInitial){
}else if (state is HomeErrorState){
showInSnackBar(context, state.error);
}else if(state is HomeLoadedState){
// devList?.addAll(state.devList);
devList= state.devList;
devList?.add(_selected);
}else if(state is HomeSelectedState){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnitsPage(
devCode: state.devCode,
devName: state.devName,
)
)
);
}
},
child: Scaffold(
appBar: AppBar(
title: const Text("Home"),
),
body: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
if (state is HomeLoadingState) {
return const Center(
child: CircularProgressIndicator()
);
} else {
return Center(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(color: MyColors.colorBlack),
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton<Development>(
// Initial Value
value: _selected,
isExpanded: true,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
iconSize: 25,
// Array list of items
items: devList?.map<DropdownMenuItem<Development>>((Development value) {
return DropdownMenuItem<Development>(
value: value,
child: Text(value.dEVNAME!),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (newVal) => setState(() => _selected = newVal!),
)
),
SizedBox(
height: 20,
),
Container(
width: double.infinity,
padding:
EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: ElevatedButtonWidget(
onPressed: () {
if(_selected.dEVCODE!="0"){
BlocProvider.of<HomeBloc>(context).add(
DevSelectEvent(
devCode:_selected.dEVCODE,
devName: _selected.dEVNAME,
)
);
}else{
String msg = "please "+_selected.dEVNAME!;
showInSnackBar(context, msg);
}
},
text: 'Search',
),
)
],
),
),
);
}
},
),
),
),
);
}
void showInSnackBar(BuildContext context, String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
// duration: Duration(seconds: 2),
),
);
}
}
主场
class HomeBloc extends Bloc<HomeEvent, HomeState> {
HomeBloc() : super(HomeInitial()) {
on<HomeEvent>((event, emit) async {
// TODO: implement event handler
if(event is GetDevEvent){
emit(HomeLoadingState());
try{
DevData devList = await getData();
if(devList.result =="1"){
emit(HomeLoadedState(devList.development));
print("data.."+ devList.toString());
}else{
emit(HomeErrorState("No data Found"));
}
}catch (e){
print("error..."+e.toString());
emit(HomeErrorState("Failed"));
}
}
if(event is DevSelectEvent){
emit(HomeLoadingState());
emit(HomeSelectedState(event.devName!,event.devCode!));
}
});
}
Future<DevData> getData() async {
final Dio _dio = Dio();
final response = await _dio.post(AppConstants.getDevs);
final jsonResponse =response.data;
print(jsonResponse.toString());
return DevData.fromJson(jsonResponse);
}
}
错误日志:
Bad state: Tried to read a provider that threw during the creation of its value.
The exception occurred during the creation of type HomeBloc.
══╡ EXCEPTION CAUGHT BY PROVIDER ╞═══════════════════════════════
The following StateError was thrown:
Bad state: Cannot add new events after calling close
When the exception was thrown, this was the stack:
#1 Bloc.add (package:bloc/src/bloc.dart:84:24)
#2 _HomePageState.build.<anonymous closure> (package:watchman/Home/HomePage.dart:39:64)
#3 _CreateInheritedProviderState.value (package:provider/src/inherited_provider.dart:729:36)
#4 _InheritedProviderScopeElement.value (package:provider/src/inherited_provider.dart:583:33)
#5 Provider.of (package:provider/src/provider.dart:303:37)
#6 ReadContext.read (package:provider/src/provider.dart:656:21)
#7 _BlocListenerBaseState.initState (package:flutter_bloc/src/bloc_listener.dart:147:36)
#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4942:57)
#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#10 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
#11 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#12 Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
#13 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4832:16)
#14 _InheritedProviderScopeElement.performRebuild (package:provider/src/inherited_provider.dart:495:11)
#15 Element.rebuild (package:flutter/src/widgets/framework.dart:4529:5)
#16 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4787:5)
#17 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#18 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:395:11)
... Normal element mounting (7 frames)
#25 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (7 frames)
#32 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (283 frames)
#315 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#316 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6350:36)
#317 Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
#318 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5883:32)
#319 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6375:17)
#320 Element.updateChild (package:flutter/src/widgets/framework.dart:3530:15)
#321 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4832:16)
#322 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4977:11)
我通过在 initstate() 中添加我的第一个事件而不是 BlocProvder 来解决这个问题。
late HomeBloc bloc;
// Initial Selected Value
@override
void initState() {
// TODO: implement initState
bloc = HomeBloc();
bloc.add(GetDevEvent());
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
bloc.close();
super.dispose();
}