flutter - 使用 API 实现 bloc 模式会导致异常“type 'Future' 不是 'Widget?' 类型的子类型?
问题描述
我正在尝试实现 bloc 模式,其中我正在使用一个存储库类,该存储库类包含使用 API 进行调用的所有方法。另一方面,我正在实现 BlocBuilder 以根据 bloc 状态呈现视图但是我收到此错误 BlocBuilder<VehiclesBloc, VehiclesState>(dirty, dependencies: [_LocalizationsScope-[GlobalKey#df8d0]], state: _BlocBuilderBaseState<VehiclesBloc, VehiclesState >#dba40):“未来”类型不是“小部件?”类型的子类型
我真的不确定问题来自哪里。这是代码的一些片段。
这是导致错误的 bloc 类
class VehiclesBloc extends Bloc<VehiclesEvent,VehiclesState>{
VehiclesBloc(VehiclesState initialState) : super(initialState);
@override
Stream<VehiclesState> mapEventToState(VehiclesEvent event) async* {
// TODO: implement mapEventToState
if(event is LoadVehiclesList){
yield* mapLoadEventToState(event);
}
}
Stream<VehiclesState> mapLoadEventToState(LoadVehiclesList event) async* {
if(event is LoadVehiclesList){
var response = await VehiclesService().getAll();
if(response.IsSuccess){
yield VehiclesLoaded(response.Data);
}else{
yield VehiclesLoadingFailed(response.ErrorList.toString());
}
}else{
yield VehiclesLoading();
}
}
}
这是实现 Bloc Builder 的 Statefull 小部件
class VehicleList extends StatefulWidget {
const VehicleList({Key key}) : super(key: key);
static const String routeName = "/VehicleList";
//final ScrollController scrollController;
@override
_VehicleListState createState() => _VehicleListState();
}
class _VehicleListState extends State<VehicleList> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
VehiclesBloc vehiclesBloc =
VehiclesBloc(VehiclesLoading())..add(LoadVehiclesList());
@override
void initState() {
// TODO: implement initState
super.initState();
//VehiclesService().getAll();
}
@override
void dispose() {
// TODO: implement dispose
vehiclesBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
final isRtl = context.locale.languageCode == "ar";
return Scaffold(
key: _scaffoldKey,
backgroundColor: kBackgroundColor,
drawer: SideNavigationDrawer(),
body: Container(
child: Column(
children: [
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
onPressed: () {
_scaffoldKey.currentState.openDrawer();
},
icon: Icon(
Icons.menu,
size: 35,
color: Colors.black,
),
)
],
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
BlocBuilder<VehiclesBloc,VehiclesState>(
builder: (context, state) {
if (state is VehiclesLoaded) {
// return BuildListVehicle(state.lsVehicle);
return Center();
} else if (state is VehiclesLoadingFailed) {
return Center(
child: CustomErrorWidget(),
);
} else {
return Center(
child: LoadingDialog.showLoadingDialog(context,
text: ""),
);
}
},
cubit: vehiclesBloc,
),
],
),
),
)
],
),
));
}
解决方案
我认为这个代码部分会导致问题:
return Center(
child: LoadingDialog.showLoadingDialog(context,text: ""),
);
可能LoadingDialog.showLoadingDialog
不会返回 Widget,而只是返回 Future 的函数。
对于副作用(例如,您想显示对话框),您应该使用侦听器而不是在 build 方法中执行此类代码。而不是BlocBuilder
,只需使用BlocConsumer
并添加侦听器:
BlocConsumer<VehiclesBloc,VehiclesState>(
listener: (context, state) {
if (state is {your loading state}) {
LoadingDialog.showLoadingDialog(context, text: "");
}
},
builder: ...,
),
有关您的代码的更多见解:
- 不要在有状态的小部件中创建 BLoC 作为变量,而是使用 BlocProvider 来处理 BLoC 的创建/处置部分。
- 在加载数据之前产生
VehiclesLoading
状态,而不仅仅是“其他”情况。这样您就可以在 UI 中轻松处理加载行为。要解决上述问题,只需遵循文档:https ://bloclibrary.dev/
推荐阅读
- python - 如果 int() 提供非整数,如何处理 ValueError
- indexing - 我可以从 CosmosDB 中的新索引布局中获得什么性能差异?
- go - [][]string 与包含 []string 的结构的内存使用情况
- postgresql - 如何强制 PostgreSQL 创建带有 'pg_' 保留前缀的模式
- reactjs - 卸载子组件抛出无法在 reactjs 中的卸载组件上调用 setstate
- node.js - How to update a value with aggregate in mongodb and node
- excel - 为什么 MS EXCEL.. 中没有 SUBTRACT 和 DIVISION 功能?
- python - 词云不适用于 pyinstaller
- python - 构建相关数据字段验证烧瓶 WTF
- c++ - 设置流状态以在格式化输出运算符(运算符<<)中传达错误