【发布时间】: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 错误,所以我现在直接从屏幕提供它我从中导航,但设置不正确。
你能发现我在这里做错了吗?
一如既往,非常感谢您的时间和帮助。
【问题讨论】: