【问题标题】:Passing BlocProvider through Navigator Flutter通过 Navigator Flutter 传递 BlocProvider
【发布时间】:2020-07-21 23:43:56
【问题描述】:

我正在使用flutter_blocpackage,并从抽屉中的一个按钮发送一个加载保存的警报的SchedulerEvent,并且,提供SchedulerBloc,我导航到一个SchedulerScreen,它有一个BlocListener来监听SchedulerState 并显示所有设置的警报。 当按下按钮面团时,我在按钮的onPressed:回调中收到由BlocProvider.of<SchedulerBloc>(context).add(LoadAlarms());引起的错误。:

E/flutter (13058): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'handleError' was called on null.
E/flutter (13058): Receiver: null
E/flutter (13058): Tried calling: handleError(Closure: (Object, [StackTrace]) => void from Function '_handleError@73502097':.)
E/flutter (13058): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter (13058): #1      Bloc._bindStateSubject.<anonymous closure> (package:bloc/src/bloc.dart:155:44)
E/flutter (13058): #2      Stream.asyncExpand.onListen.<anonymous closure> (dart:async/stream.dart:576:30)
E/flutter (13058): #3      _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (13058): #4      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (13058): #5      _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter (13058): #6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
E/flutter (13058): #7      _DelayedData.perform (dart:async/stream_impl.dart:593:14)
E/flutter (13058): #8      _StreamImplEvents.handleNext (dart:async/stream_impl.dart:709:11)
E/flutter (13058): #9      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:669:7)
E/flutter (13058): #10     _rootRun (dart:async/zone.dart:1122:38)
E/flutter (13058): #11     _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (13058): #12     _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter (13058): #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
E/flutter (13058): #14     _rootRun (dart:async/zone.dart:1126:13)
E/flutter (13058): #15     _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (13058): #16     _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter (13058): #17     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
E/flutter (13058): #18     _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
E/flutter (13058): #19     _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
E/flutter (13058):  

这是导航到SchedulerScreen 的按钮:

FlatButton.icon(
                          icon: Image.asset(
                            'assets/schedulerButton.png',
                            height: 55,
                            width: 55,
                          ),
                          label: Text(
                            'Check scheduler',
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 18,
                                fontWeight: FontWeight.w400),
                          ),
                          color: Colors.transparent,
                          onPressed: () {
                            // TODO call LoadRoutes and navigate to SchedulerScreen
                            print('pressed');
                            cache.play('tableViewOpen.mp3');

                            BlocProvider.of<SchedulerBloc>(context)
                                .add(LoadAlarms());

                            // old
                            // old
//                            Navigator.push(
//                              context,
//                              MaterialPageRoute(
//                                builder: (context) =>
//                                    SchedulerScreen(widget.key, widget.user),
//                              ),
//                            );
                            // new
                            Navigator.push(
                              context,
                              MaterialPageRoute<SchedulerScreen>(builder: (_) {
                                return BlocProvider.value(
                                  value:
                                      BlocProvider.of<SchedulerBloc>(context),
                                  child:
                                      SchedulerScreen(widget.key, widget.user),
                                );
                              }),
                            );
                          },
                        ),

这是SchedulerScreen,应显示SchedulerState 附带的已保存警报:

class SchedulerScreen extends StatefulWidget {
  final User user;
  SchedulerScreen(Key key, this.user);
  @override
  _SchedulerScreenState createState() => _SchedulerScreenState();
}

class _SchedulerScreenState extends State<SchedulerScreen> {
  AudioCache cache = new AudioCache();

  List<Alarm> alarms = [];
  List<SchedulerCell> cells = [];

  @override
  Widget build(BuildContext context) {
    cache.loadAll(['click.mp3', 'tableViewOpen.mp3', 'tableViewClose.mp3']);
    dynamic backButton =
        Platform.isIOS ? CupertinoIcons.back : Icons.arrow_back;
    dynamic addButton = Platform.isIOS ? CupertinoIcons.add : Icons.add;
//    return BlocProvider<SchedulerBloc>(
//      create: (BuildContext context) => SchedulerBloc(),
//      child: BlocListener<SchedulerBloc, SchedulerState>(
    return BlocListener<SchedulerBloc, SchedulerState>(
      listener: (BuildContext context, SchedulerState state) {
        if (state is AlarmsLoaded) {
          setState(() {
            alarms = state.alarms;
            cells = state.cells;
          });
        }
      },
      child: Scaffold(
//    return Scaffold(
        appBar: AppBar(
          elevation: 0,
          backgroundColor: Colors.transparent,
          leading: IconButton(
              icon: Icon(backButton),
              color: Colors.redAccent,
              onPressed: () {
                cache.play('tableViewClose.mp3');
                Navigator.pop(context);
              }),
          title: Text(
            'Controlli tragitti',
            textAlign: TextAlign.center,
            style: TextStyle(
                color: Colors.orange,
                fontSize: 22,
                fontWeight: FontWeight.w500,
                letterSpacing: 1),
          ),
          centerTitle: true,
          actions: <Widget>[
            IconButton(
              icon: Icon(addButton),
              color: Colors.redAccent,
              onPressed: () {
                // TODO navigate to AddEditCheckScreen
                cache.play('tableViewOpen.mp3');
//                  Navigator.push(
//                    context,
//                    MaterialPageRoute(
//                      builder: (context) => AddEditCheckScreen(
//                          key: widget.key, isEditing: false, user: widget.user),
//                    ),
//                  );
                Navigator.push(
                  context,
                  MaterialPageRoute<AddEditCheckScreen>(builder: (_) {
                    return BlocProvider.value(
                      value: BlocProvider.of<SchedulerBloc>(context),
                      child: AddEditCheckScreen(
                          key: widget.key, isEditing: false, user: widget.user),
                    );
                  }),
                );
              },
            )
          ],
        ),
        body: Container(),
//          body: ListView.builder(
//            padding: EdgeInsets.all(20),
//            itemCount: alarms.length,
//            itemBuilder: (BuildContext context, int index) => Container(
//              color: Colors.transparent,
//              child: cells[index],
//            ),
//          ),
//        ),
      ),
    );
  }
}

如您所见,我最初是直接在 SchedulerScreen 中创建 BlocProvider,因为从那里我还添加了新警报,但是从它发送事件时我收到了 BlocProvider.of() called with a context that does not contain a Bloc of type SchedulerBloc 错误,所以我现在直接从屏幕提供它我从中导航,但设置不正确。 你能发现我在这里做错了吗? 一如既往,非常感谢您的时间和帮助。

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    我发现错误在SchedulerBlocmapEventToState 方法中没有被声明为async*。添加后一切正常。

    【讨论】:

      猜你喜欢
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      • 2022-08-13
      • 1970-01-01
      • 2018-11-15
      • 2021-06-22
      相关资源
      最近更新 更多