使用 API 实现 bloc 模式导致异常 "type 'Future<dynamic>' is not a subtype of type 'Widget?'"

implementing bloc pattern with API cause an exception "type 'Future<dynamic>' is not a subtype of type 'Widget?'"

我正在尝试实现 bloc 模式,我在其中使用存储库 class,其中包含使用 API 进行调用的所有方法。另一方面,我正在实施 BlocBuilder 以根据 bloc 状态呈现视图,但是我收到此错误 BlocBuilder(dirty, dependencies: [_LocalizationsScope-[GlobalKey#df8d0]], state: _BlocBuilderBaseState#dba40): 类型 'Future' 不是类型 'Widget?'

的子类型

我真的不确定问题出在哪里。这是一些代码片段。

这是导致错误的块class

  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 不是 return 小部件,而只是 return 未来的一个功能。

对于副作用(例如,您想显示对话框),您应该使用侦听器而不是在构建方法中执行此类代码。而不是 BlocBuilder,只需使用 BlocConsumer 并添加侦听器:

BlocConsumer<VehiclesBloc,VehiclesState>(
  listener: (context, state) {
    if (state is {your loading state}) {
      LoadingDialog.showLoadingDialog(context, text: "");
    }
  },
  builder: ...,
),

关于您的代码的更多见解:

  1. 不要将 BLoC 创建为有状态小部件中的变量,而是使用 BlocProvider 来处理 BLoC 的 create/dispose 部分。
  2. 在加载数据之前产生 VehiclesLoading 状态,而不仅仅是作为“其他”情况。这样您就可以在 UI 中轻松处理加载行为。 要解决上述问题,只需按照文档:https://bloclibrary.dev/