使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()
Posted
技术标签:
【中文标题】使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()【英文标题】:Flutter BlocProvider.of() called with a context that does not contain a Bloc of type 【发布时间】:2020-12-26 16:52:33 【问题描述】:我正在从第一个屏幕导航到第二个屏幕。我在第二个屏幕中使用 Bloc Pattern。我收到以下错误:
BlocProvider.of() called with a context that does not contain a Bloc of type
No ancestor could be found starting from the context that was passed to BlocProvider.of<MyBloc>().
This can happen if:
1. The context you used comes from a widget above the BlocProvider.
2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.
下面是我的导航代码
BlocProvider<MyBloc>(
create: (context) => MyBloc());
Navigator.push(context, MaterialPageRoute(builder: (context)
return SecondScreen(context);
));
下面是我的 SecondScreen 类
class SecondScreen extends StatefulWidget
@override
_SecondScreenState createState() => _SecondScreenState();
class _SecondScreenState extends State<SecondScreen>
MyBloc myBloc;
@override
void initState()
super.initState();
myBloc = BlocProvider.of<MyBloc>(context);
myBloc.add(FetchEvents());
@override
Widget build(BuildContext context)
return MaterialApp(
home: Builder(
builder: (context)
return Material(
child: Scaffold(
appBar: AppBar(
title: Text("New Screen"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: ()
myBloc.add(FetchEvents());
,
),
IconButton(
icon: Icon(Icons.info),
onPressed: ()
,
)
],
),
body: Container(
child: BlocListener<MyBloc, MyState>(
listener: (context, state)
if (state is MyErrorState)
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(state.message),
),
);
,
child: BlocBuilder<MyBloc, MyState>(
builder: (context, state)
if (state is MyInitialState)
return buildLoading();
else if (state is MyLoadingState)
return buildLoading();
else if (state is MyLoadedState)
return buildArticleList(state.yList);
else if (state is MyErrorState)
return buildErrorUi(state.message);
,
),
),
),
),
);
,
),
);
Widget buildLoading()
return Center(
child: CircularProgressIndicator(),
);
Widget buildErrorUi(String message)
return Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
message,
style: TextStyle(color: Colors.red),
),
),
);
Widget buildArticleList(List<Data> data)
return ListView.builder(
itemCount: data.length,
itemBuilder: (ctx, pos)
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
child: ListTile(
title: Text(data[pos].title),
subtitle: Text(data[pos].shortDesc),
),
onTap: ()
// navigateToArticleDetailPage(context, articles[pos]);
,
),
);
,
);
我刚开始学习 bloc 并卡在这里.. 任何人都可以帮忙。
我没有在 main.dart 中添加任何与 bloc 相关的内容。有必要吗?
【问题讨论】:
【参考方案1】:问题出在这部分:
BlocProvider<MyBloc>(
create: (context) => MyBloc());
Navigator.push(context, MaterialPageRoute(builder: (context)
return SecondScreen(context);
));
把它改成这个大概会修复它:
BlocProvider<MyBloc>(
create: (context) => MyBloc());
Navigator.push(context, MaterialPageRoute(
builder: (routeContext) => SecondScreen(),
));
【讨论】:
The following SecondInitialState object was throwed building SecondScreen(state: _SecondScreenState#fe7f9): SecondInitialState 相关的导致错误的小部件是 SecondScreen lib/.../widgets/List.dart:49 抛出异常时,这是堆栈 #0 MyBloc.initialState #1 new Bloc #2 new MyBloc #3 _SecondScreenState.build. #4 BuilderStateDelegate.initDelegate 这似乎与您的集团问题无关,您的集团内部逻辑似乎有问题【参考方案2】:将使用的widget
包裹在BlocProvider
内,这将提供正确的上下文以供使用。
BlocProvider(
create: (BuildContext context)
return _yourBloc;
,
child: Widget(
【讨论】:
【参考方案3】:要在您正在导航的页面中使用相同的块,请使用 BlocProvider.value()。
改变
Navigator.push(context, MaterialPageRoute(builder: (context)
return SecondScreen(context);
));
到
Navigator.push(context, MaterialPageRoute(builder: (context)
return BlocProvider<MyBloc>.value(
value: BlocProvider.of<MyBloc>(context),
child: SecondScreen(context),
);
));
确保有一个 MyBloc 类型的父 BlocProvider。简单示例:
BlocProvider<MyBloc>(
create: (context) => MyBloc(),
child: Builder(
builder: (context) => YourWidget(),//Wrap with Builder to access BlocProvider's context
),
);
我还强烈建议您查看this video 以获得更好的解释。
另外,this issue 可能会有所帮助。
【讨论】:
以上是关于使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()的主要内容,如果未能解决你的问题,请参考以下文章
使用不包含 Bloc 类型的上下文调用 BlocProvider.of()
BlocProvider.of() 使用不包含 Bloc<dynamic,dynamic> 类型的 Bloc 的上下文调用
使用不包含 PhoneAuthenticationBloc 类型的 Bloc 的上下文调用 BlocProvider.of()。扑
使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()