无法在此应用程序小部件上方找到正确的提供者<TokenBloc>
Could not find the correct Provider<TokenBloc> above this App Widget
我使用 BLoC。如何正确创建它,不会出现由于缺少小部件树下的小部件而不会出现的情况。现在我通常是这样的:
Widget build(BuildContext context) {
return MaterialApp(
// debugShowCheckedModeBanner: false,
theme: Styles.appTheme,
home: BlocProvider<TokenBloc>(
create: (context) => di.sl<TokenBloc>(),
child: _childTokenBloc,
),
);
}
Widget get _childTokenBloc {
return BlocBuilder<TokenBloc, TokenState>(builder: (context, state) {
if (state is TokenInitialState) {
context.read<TokenBloc>().add(TokenCheckEvent());
return const LogoImage();
}
if (state is TokenCheckState) {
return const LogoImage();
}
if (state is TokenOkState) {
return MainPageWidget();
}
if (state is TokenNoAuthorizationState) {
return const AuthorizationPageWidget();
}
return const LogoImage();
}
);
}
在 AuthorizationPageWidget 中我这样做:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ConfirmAuthorizationPage()),
);
我尝试从 ConfirmAuthorizationPage 转向 TokenBloc:
context.read<TokenBloc>().add(TokenAddEvent());
但我收到错误:在此应用小部件上方找不到正确的提供程序
我以为TokenBloc 会在widget 树中找到,但不是吗?以及如何解决这个问题?需要在 ConfirmAuthorizationPage 小部件的构建方法中使用 MultiBlocProvider 吗?会重新初始化,之前的就不用了
更新 1:
代码 AuthorizationPageWidget:
class AuthorizationPageWidget extends StatefulWidget {
const AuthorizationPageWidget({Key? key}) : super(key: key);
@override
_AuthorizationPageWidgetState createState() =>
_AuthorizationPageWidgetState();
}
class _AuthorizationPageWidgetState extends State<AuthorizationPageWidget> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider<AuthorizationBloc>(
create: (context) => sl<AuthorizationBloc>(),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_title,
_description,
Expanded(child: Align(alignment: FractionalOffset.bottomCenter, child: _bottomButton))
],
),
),
),
);
}
//......
void pushConfirmPage(String number) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ConfirmAuthorizationPage(number: number,)),
);
}
}
如果你想在你所有的应用程序中提供你的 Bloc,你必须像这样在你的 MaterialApp 中写它,而不是在正文中;
return
BlocProvider<TokenBloc>( // like this
create: (context) => TokenBloc(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: _TokenHome(),
),
),
);
class _TokenHome extends StatelessWidget { // use a class instead of function
const _TokenHome({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<TokenBloc, TokenState>(
builder: (context, state) {
if (state is TokenInitialState) {
context.read<TokenBloc>().add(TokenCheckEvent());
return const LogoImage();
}
if (state is TokenCheckState) {
return const LogoImage();
}
if (state is TokenOkState) {
return MainPageWidget();
}
if (state is TokenNoAuthorizationState) {
return const AuthorizationPageWidget();
}
return Container(
width: 50,
height: 50,
color: Colors.red,
); // use this if there is not a state
}
);
}
}
如果由于某种原因它不再显示任何内容,那是因为你的某些 类 像 AuthorizationPageWidget 或 LogoImage 是错误的,检查一下。
-------- 编辑
在每个页面上使用 BlocProvider 可能很有用,但请记住,例如 AuthorizationBloc 仅适用于其子页面,如果你在屏幕的另一边调用它不会起作用,所以强烈建议在 MaterialApp 中使用 MultiBlocProvider 以避免将来出现问题;
return MultiBlocProvider( // like this
providers: [
BlocProvider<TokenBloc>(
create: (context) => TokenBloc(),
),
BlocProvider<AuthorizationBloc>(
create: (context) => AuthorizationBloc(),
),
],
child: BlocBuilder<LanguageCubit, Locale?>(
builder: (context, lang) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
);
},
),
);
所以你用来创建的所有其他 BlocProvider,删除它们,你不需要它们,现在如果你使用 BlocBuilder, 任何 Bloc 的 BlocListeners,您不会有任何不便。
我使用 BLoC。如何正确创建它,不会出现由于缺少小部件树下的小部件而不会出现的情况。现在我通常是这样的:
Widget build(BuildContext context) {
return MaterialApp(
// debugShowCheckedModeBanner: false,
theme: Styles.appTheme,
home: BlocProvider<TokenBloc>(
create: (context) => di.sl<TokenBloc>(),
child: _childTokenBloc,
),
);
}
Widget get _childTokenBloc {
return BlocBuilder<TokenBloc, TokenState>(builder: (context, state) {
if (state is TokenInitialState) {
context.read<TokenBloc>().add(TokenCheckEvent());
return const LogoImage();
}
if (state is TokenCheckState) {
return const LogoImage();
}
if (state is TokenOkState) {
return MainPageWidget();
}
if (state is TokenNoAuthorizationState) {
return const AuthorizationPageWidget();
}
return const LogoImage();
}
);
}
在 AuthorizationPageWidget 中我这样做:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ConfirmAuthorizationPage()),
);
我尝试从 ConfirmAuthorizationPage 转向 TokenBloc:
context.read<TokenBloc>().add(TokenAddEvent());
但我收到错误:在此应用小部件上方找不到正确的提供程序
我以为TokenBloc 会在widget 树中找到,但不是吗?以及如何解决这个问题?需要在 ConfirmAuthorizationPage 小部件的构建方法中使用 MultiBlocProvider 吗?会重新初始化,之前的就不用了
更新 1: 代码 AuthorizationPageWidget:
class AuthorizationPageWidget extends StatefulWidget {
const AuthorizationPageWidget({Key? key}) : super(key: key);
@override
_AuthorizationPageWidgetState createState() =>
_AuthorizationPageWidgetState();
}
class _AuthorizationPageWidgetState extends State<AuthorizationPageWidget> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider<AuthorizationBloc>(
create: (context) => sl<AuthorizationBloc>(),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_title,
_description,
Expanded(child: Align(alignment: FractionalOffset.bottomCenter, child: _bottomButton))
],
),
),
),
);
}
//......
void pushConfirmPage(String number) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ConfirmAuthorizationPage(number: number,)),
);
}
}
如果你想在你所有的应用程序中提供你的 Bloc,你必须像这样在你的 MaterialApp 中写它,而不是在正文中;
return
BlocProvider<TokenBloc>( // like this
create: (context) => TokenBloc(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: _TokenHome(),
),
),
);
class _TokenHome extends StatelessWidget { // use a class instead of function
const _TokenHome({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<TokenBloc, TokenState>(
builder: (context, state) {
if (state is TokenInitialState) {
context.read<TokenBloc>().add(TokenCheckEvent());
return const LogoImage();
}
if (state is TokenCheckState) {
return const LogoImage();
}
if (state is TokenOkState) {
return MainPageWidget();
}
if (state is TokenNoAuthorizationState) {
return const AuthorizationPageWidget();
}
return Container(
width: 50,
height: 50,
color: Colors.red,
); // use this if there is not a state
}
);
}
}
如果由于某种原因它不再显示任何内容,那是因为你的某些 类 像 AuthorizationPageWidget 或 LogoImage 是错误的,检查一下。
-------- 编辑
在每个页面上使用 BlocProvider 可能很有用,但请记住,例如 AuthorizationBloc 仅适用于其子页面,如果你在屏幕的另一边调用它不会起作用,所以强烈建议在 MaterialApp 中使用 MultiBlocProvider 以避免将来出现问题;
return MultiBlocProvider( // like this
providers: [
BlocProvider<TokenBloc>(
create: (context) => TokenBloc(),
),
BlocProvider<AuthorizationBloc>(
create: (context) => AuthorizationBloc(),
),
],
child: BlocBuilder<LanguageCubit, Locale?>(
builder: (context, lang) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
);
},
),
);
所以你用来创建的所有其他 BlocProvider,删除它们,你不需要它们,现在如果你使用 BlocBuilder, 任何 Bloc 的 BlocListeners,您不会有任何不便。