Nef*_*ous 9 dialog flutter bloc
我正在尝试使用块来管理对话框的内容。我对扑动相当陌生。
该页面定义为:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Business Region Manager"),
),
body: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
EntityModifyBloc(repository: widget.repository),
),
BlocProvider(
create: (context) => EntityBloc(
repository: widget.repository,
modifyBloc: BlocProvider.of<EntityModifyBloc>(context)),
),
BlocProvider(
create: (context) => BusinessRegionBloc(repository: widget.repository),
),
],
child: Center(
child: BusinessRegionPage(widget.business),
),
));
}
Run Code Online (Sandbox Code Playgroud)
在 BusinessRegionPage 内部,我使用了 EntityBloc 和 EntityModifyBloc,并且,我至少认为我的做法是正确的。该页面有一个回调,当触发时会调用一个方法:
void onAddBusinessRegion(){
showDialog(context: context,
barrierDismissible: false,
builder: (BuildContext context){
return BusinessRegionDialog(
positiveText: "Ok",
onPositive: onPositive,
negativeText: 'Cancel',
onNegative: onNegative,
businessId: widget.business.id,
);
});
}
Run Code Online (Sandbox Code Playgroud)
BusinessRegionDialog 是一个有状态的小部件,状态实现构建是:
@override
Widget build(BuildContext context) {
return BlocBuilder<BusinessRegionBloc, BusinessRegionState>(builder: (context, state) {
if (state is BusinessRegionEmpty) {
BlocProvider.of<BusinessRegionBloc>(context).add(GetBusinessRegions(widget.businessId));
}
if (state is BusinessRegionError) {
return Center(
child: Text('Busines Region Error'),
);
}
if (state is BusinessRegionLoaded) {
return Center(
child: Text('BusinessRegionLoaded'),
);
}
return Center(
child: CircularProgressIndicator(),
);
});
Run Code Online (Sandbox Code Playgroud)
当回调被触发时,我收到消息:
错误:在此 BlocBuilder<BusinessRegionBloc, BusinessRegionState> 小部件上方找不到正确的提供程序
发生这种情况可能是因为您使用的提供商BuildContext不包括您选择的提供商。
我假设在调用 ShowDialog(context) 时,上下文与传递到 build 的上下文相同?我通过在 showDialog 调用之前和 BusinessRegionPage 上的构建实现之后打印上下文的 hashCode 来检查这个假设,
错误消息中的建议之一是:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
builder: (context) {
return Text(context.watch<Example>()),
}
),
}
Run Code Online (Sandbox Code Playgroud)
所以我尝试了:
void onAddBusinessRegion() {
print("OnAddCallback: " + context.hashCode.toString());
BusinessRegionClient brClient = BusinessRegionClient(client: http.Client());
BusinessRegionRepository brRepository =
BusinessRegionRepository(client: brClient);
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return Provider<BusinessRegionBloc>(
create: (_) => BusinessRegionBloc(repository: brRepository),
builder: (context) {
return BusinessRegionDialog(
positiveText: "Ok",
onPositive: onPositive,
negativeText: 'Cancel',
onNegative: onNegative,
businessId: widget.business.id,
);
});
});
}
Run Code Online (Sandbox Code Playgroud)
IDE 告诉我:参数类型“BusinessRegionDialog Function(BuildContext)”无法分配给参数类型“Widget Function(BuildContext, Widget)”。
我显然不明白什么。我想做的就是用我的存储库中的 Future 信息填充一个对话框。任何指导将不胜感激。
BlocProvider.value在构建器参数中使用showDialog。
onPress: () async {
await showDialog(
context: context,
builder: (_) {
return BlocProvider.value(
value: BlocProvider.of<BlocA>(context),
child: SimpleDialogWidget(),
);
},
);
}
Run Code Online (Sandbox Code Playgroud)
I finally figured it out thanks to the so entry:
Flutter: bloc, how to show an alert dialog
这里的答案是使用堆栈使对话框和页面共存,并在侦听器具有正确状态时显示对话框。答案使用 StatelessWidget 来管理(在答案的情况下),即 SnackBar。为了能够向块添加事件,我使用了 StatefulWidget。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Business Region Manager"),
),
body: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => EntityModifyBloc(
repository: xbrRepository), //widget.repository),
),
BlocProvider(
create: (context) => EntityBloc(
repository: xbrRepository, //widget.repository,
modifyBloc: BlocProvider.of<EntityModifyBloc>(context)),
),
BlocProvider(
create: (context) => BusinessRegionDialogBloc(
repository: xbrRepository),
),
],
child: Stack(children: [
BusinessRegionDialogManager(widget.business.id),
Center(child: BusinessRegionPage(widget.business)),
]),
));
}
class BusinessRegionDialogManager extends StatefulWidget {
final int businessId;
BusinessRegionDialogManager(this.businessId);
State<BusinessRegionDialogManager> createState() =>
_BusinessRegionDialogManagerState();
}
class _BusinessRegionDialogManagerState
extends State<BusinessRegionDialogManager> {
// Callback functions from the dialog so can have access to
// BusinessRegionDialogBloc
void xnPositive(List<Region> addedRegions) {
BlocProvider.of<BusinessRegionDialogBloc>(context)
.add(AddBusinessRegions(addedRegions, widget.businessId));
}
void xnNegative(){
}
@override
Widget build(BuildContext context) {
return BlocListener<BusinessRegionDialogBloc, BusinessRegionDialogState>(
listener: (context, state) {
if (state is RegionDialogLoaded) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return BusinessRegionDialog(
onPositive: xnPositive,
onNegative: xnNegative,
regions: state.regions,
);
})
}
},
child: Container(),
);
}
Run Code Online (Sandbox Code Playgroud)