以前,我是在main.dart中初始化我的PersonBlocProvider
return PersonBlocProvider(
personBloc: PersonBloc(this._apiInterface),
child: AlarmBlocProvider(
alarmBloc: AlarmBloc(this._apiInterface),
child: EventBlocProvider(
eventBloc: EventBloc(this._apiInterface),
child: MaterialApp(
title: 'Hat Mobile',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: LoginScreen(),
)
)
)
);
并在另一个视图中使用BLOC:
class AlarmView extends StatelessWidget {
Widget build(BuildContext context) {
final personBlocProvider = PersonBlocProvider.of(context);
final alarmBlocProvider = AlarmBlocProvider.of(context);
return
DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
actions: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, right: 10),
child: Text(StringLiterals.ALARM_TEXT)),
Padding(
padding: EdgeInsets.only(right: 15),
child: _BuildSwitch(bloc: alarmBlocProvider))
],
title: Text(StringLiterals.PAGE_TITLE_ALARM),
bottom: MyTabBar(),
),
body: TabBarView(
children: <Widget>[
_ListPage(StringLiterals.PRESENT, personBlocProvider),
_ListPage(StringLiterals.SAFE, personBlocProvider),
_ListPage(StringLiterals.UNKNOWN, personBlocProvider),
_ListPage(StringLiterals.HOLIDAY, personBlocProvider),
],
),
),
);
}
}
此方法有效,但是在应用启动后就产生了BLoC,我意识到我不想要这样。
所以我决定将BlocProviders从main移到我的视图文件中。
我的主要爱好变成了
return MaterialApp(
title: 'Hat Mobile',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: LoginScreen(),
);
并查看:
class AlarmView extends StatelessWidget {
Widget build(BuildContext context) {
final personBlocProvider = PersonBlocProvider.of(context);
final alarmBlocProvider = AlarmBlocProvider.of(context);
return PersonBlocProvider(
personBloc: PersonBloc(BlueApiMock()),
child: AlarmBlocProvider(
alarmBloc: AlarmBloc(BlueApiMock()),
child: DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
actions: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, right: 10),
child: Text(StringLiterals.ALARM_TEXT)),
Padding(
padding: EdgeInsets.only(right: 15),
child: _BuildSwitch(bloc: alarmBlocProvider))
// child: _BuildSwitch(bloc: AlarmBloc(BlueApiMock())))
],
title: Text(StringLiterals.PAGE_TITLE_ALARM),
bottom: MyTabBar(),
),
body: TabBarView(
children: <Widget>[
_ListPage(StringLiterals.PRESENT, personBlocProvider),
_ListPage(StringLiterals.SAFE, personBlocProvider),
_ListPage(StringLiterals.UNKNOWN, personBlocProvider),
_ListPage(StringLiterals.HOLIDAY, personBlocProvider),
],
),
),
)
));
}
}
但是现在这会导致错误:
I/flutter ( 6448): The following NoSuchMethodError was thrown building AlarmView(dirty):
I/flutter ( 6448): The getter 'personBloc' was called on null.
I/flutter ( 6448): Receiver: null
I/flutter ( 6448): Tried calling: personBloc
I/flutter ( 6448):
I/flutter ( 6448): When the exception was thrown, this was the stack:
I/flutter ( 6448): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
I/flutter ( 6448): #1 PersonBlocProvider.of (package:red_photon/alarm/providers/person_bloc_provider.dart:14:30)
I/flutter ( 6448): #2 AlarmView.build (package:red_photon/alarm/views/alarm_view.dart:17:51)
为什么现在为空?
答案 0 :(得分:2)
是的,您不能这样做,因为您传递的context
不会有任何集团祖先,而是尝试将DefaultTabController
包装在Builder
小部件中并使用该上下文(它将将集团作为小部件树中的祖先)。
示例:
class AlarmView extends StatelessWidget {
Widget build(BuildContext context) {
return PersonBlocProvider(
personBloc: PersonBloc(BlueApiMock()),
child: AlarmBlocProvider(
alarmBloc: AlarmBloc(BlueApiMock()),
child: Builder(
builder: (context) {
final personBlocProvider = PersonBlocProvider.of(context);
final alarmBlocProvider = AlarmBlocProvider.of(context);
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
actions: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, right: 10),
child: Text(StringLiterals.ALARM_TEXT)),
Padding(
padding: EdgeInsets.only(right: 15),
child: _BuildSwitch(bloc: alarmBlocProvider))
// child: _BuildSwitch(bloc: AlarmBloc(BlueApiMock())))
],
title: Text(StringLiterals.PAGE_TITLE_ALARM),
bottom: MyTabBar(),
),
body: TabBarView(
children: <Widget>[
_ListPage(StringLiterals.PRESENT, personBlocProvider),
_ListPage(StringLiterals.SAFE, personBlocProvider),
_ListPage(StringLiterals.UNKNOWN, personBlocProvider),
_ListPage(StringLiterals.HOLIDAY, personBlocProvider),
],
),
),
);
},
),
),
);
}
}
这应该有效。
希望有帮助!
答案 1 :(得分:0)
我在从抽屉导航到页面时遇到了同样的错误。下面是代码,但经过多次尝试找不到解决方案。
Navigator.push(context,MaterialPageRoute(builder: (context){
final nbloc = BlocProvider.of<NotificationBloc>(context);
return BlocProvider(child: NotificationPage(), bloc: nbloc);
}));