我正在使用flutter_bloc
软件包,并从抽屉中的按钮发送一个SchedulerEvent
来加载已保存的警报,并提供SchedulerBloc
,我导航到一个{{1} }的BlocListener可以监听SchedulerScreen
并显示所有已设置的警报。
按下按钮面团时,我在按钮的SchedulerState
回调中收到由BlocProvider.of<SchedulerBloc>(context).add(LoadAlarms());
引起的错误。
onPressed:
这是导航到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],
// ),
// ),
// ),
),
);
}
}
中创建一个BlocProvider,因为从那里我还添加了新警报,但是当从中发送事件时,我遇到了SchedulerScreen
错误,因此现在提供它直接从我从中导航的屏幕上,但是设置不正确。
您能在这里发现我做错了吗?
一如既往,非常感谢您的时间和帮助。
答案 0 :(得分:0)
我发现mapEventToState
的{{1}}方法中的错误未声明为SchedulerBloc
。添加后,一切都会按预期进行。