如何使用 MultiBlocProvider 并在子部件中传递多个提供者?
How to use MultiBlocProvider and pass multiple provider in a child widget?
我仍在学习如何使用 bloc。目前我有两个集团,PostBloc 和 LocationBloc。 PostBloc 只会调用 api 到 post 并有自己的演示文稿 ui。 LocationBloc 只会获取位置,并且可以在任何功能中全局使用。我想在 post 将其发送到服务器之前包含该位置。但我不知道如何使用这两个集团。下面的代码是我正在尝试做的一个例子。我不知道这是不是正确的做法。
class PostPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => sl<PostBloc>()),
BlocProvider(create: (_) => sl<LocationBloc>()),
],
child: Scaffold(
body: buildBody(),
),
);
}
buildBody() {
return BlocListener<PostBloc, PostState>(
listener: (context, state) {
if (state is Empty) {
} else if (state is Loading) {
} else if (state is Loaded) {
//show snackbar
} else if (state is Error) {}
},
child: InitialDisplay(),
);
}
}
class InitialDisplay extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RaisedButton(onPressed: () {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) {
return BlocProvider<PostBloc>.value(
value: BlocProvider.of<PostBloc>(context),
child: BlocProvider<LocationBloc>.value(
value: BlocProvider.of<LocationBloc>(
context),
child: PostDetails()));
});
}),
],
),
);
}
}
class PostDetails extends StatefulWidget {
const PostDetails({Key key}) : super(key: key);
@override
_PostDetailsState createState() => _PostDetailsState();
}
class _PostDetailsState extends State<PostDetails> {
double latitude;
double longitude;
@override
Widget build(BuildContext context) {
return BlocListener<LocationBloc, LocationBlocState>(
listener: (context, state) {
if (state is LocationBlocLoadedEvent) {
latitude = state.location.latitude;
longitude = state.location.longitude;
}
},
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
backgroundColor: Colors.transparent,
child: _buildWidget(context)),
);
}
_buildWidget(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * .55,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(16)),
child: RaisedButton(onPressed: () {
postWithLocation();
}));
}
void postWithLocation() {
BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
BlocProvider.of<PostBloc>(context).add(PostEvent(
post: 'Test post with location',
long: longitude,
lat: latitude,
));
}
}
编辑:
这是我得到的错误。我认为这是因为我只通过了 PostBloc,因为我不知道如何通过多个 bloc,或者这是否是正确的做法。
Error: Could not find the correct Provider<LocationBloc> above this BlocListener<LocationBloc, LocationBlocState> Widget
编辑 2:
BlocLocation 现在正在工作。我刚刚传递了与 PostBloc 相同的 blocLocation 值。我现在的问题是 PostBloc 在 postWithLocation()
函数
中提交之前没有等待 LocationBloc 获取位置
BlocProvider<PostBloc>.value(
value: BlocProvider.of<PostBloc>(context),
child: BlocProvider<LocationBloc>.value(
value: BlocProvider.of<LocationBloc>(
context),
child: PostDetails()));
这是在 Bloc
中执行排序作业的正确方法。
// _PostDetailsState
@override
Widget build(BuildContext context) {
return BlocListener<LocationBloc, LocationBlocState>(
listener: (context, state) {
if (state is LocationBlocLoadedEvent) {
final latitude = state.location.latitude;
final longitude = state.location.longitude;
BlocProvider.of<PostBloc>(context).add(PostEvent(
post: 'Test post with location',
long: longitude,
lat: latitude,
));
}
},
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
backgroundColor: Colors.transparent,
child: _buildWidget(context)),
);
}
同时删除 postWithLocation
中的一些代码。
void postWithLocation(context) {
BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
}
我仍在学习如何使用 bloc。目前我有两个集团,PostBloc 和 LocationBloc。 PostBloc 只会调用 api 到 post 并有自己的演示文稿 ui。 LocationBloc 只会获取位置,并且可以在任何功能中全局使用。我想在 post 将其发送到服务器之前包含该位置。但我不知道如何使用这两个集团。下面的代码是我正在尝试做的一个例子。我不知道这是不是正确的做法。
class PostPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => sl<PostBloc>()),
BlocProvider(create: (_) => sl<LocationBloc>()),
],
child: Scaffold(
body: buildBody(),
),
);
}
buildBody() {
return BlocListener<PostBloc, PostState>(
listener: (context, state) {
if (state is Empty) {
} else if (state is Loading) {
} else if (state is Loaded) {
//show snackbar
} else if (state is Error) {}
},
child: InitialDisplay(),
);
}
}
class InitialDisplay extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RaisedButton(onPressed: () {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) {
return BlocProvider<PostBloc>.value(
value: BlocProvider.of<PostBloc>(context),
child: BlocProvider<LocationBloc>.value(
value: BlocProvider.of<LocationBloc>(
context),
child: PostDetails()));
});
}),
],
),
);
}
}
class PostDetails extends StatefulWidget {
const PostDetails({Key key}) : super(key: key);
@override
_PostDetailsState createState() => _PostDetailsState();
}
class _PostDetailsState extends State<PostDetails> {
double latitude;
double longitude;
@override
Widget build(BuildContext context) {
return BlocListener<LocationBloc, LocationBlocState>(
listener: (context, state) {
if (state is LocationBlocLoadedEvent) {
latitude = state.location.latitude;
longitude = state.location.longitude;
}
},
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
backgroundColor: Colors.transparent,
child: _buildWidget(context)),
);
}
_buildWidget(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * .55,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(16)),
child: RaisedButton(onPressed: () {
postWithLocation();
}));
}
void postWithLocation() {
BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
BlocProvider.of<PostBloc>(context).add(PostEvent(
post: 'Test post with location',
long: longitude,
lat: latitude,
));
}
}
编辑: 这是我得到的错误。我认为这是因为我只通过了 PostBloc,因为我不知道如何通过多个 bloc,或者这是否是正确的做法。
Error: Could not find the correct Provider<LocationBloc> above this BlocListener<LocationBloc, LocationBlocState> Widget
编辑 2:
BlocLocation 现在正在工作。我刚刚传递了与 PostBloc 相同的 blocLocation 值。我现在的问题是 PostBloc 在 postWithLocation()
函数
BlocProvider<PostBloc>.value(
value: BlocProvider.of<PostBloc>(context),
child: BlocProvider<LocationBloc>.value(
value: BlocProvider.of<LocationBloc>(
context),
child: PostDetails()));
这是在 Bloc
中执行排序作业的正确方法。
// _PostDetailsState
@override
Widget build(BuildContext context) {
return BlocListener<LocationBloc, LocationBlocState>(
listener: (context, state) {
if (state is LocationBlocLoadedEvent) {
final latitude = state.location.latitude;
final longitude = state.location.longitude;
BlocProvider.of<PostBloc>(context).add(PostEvent(
post: 'Test post with location',
long: longitude,
lat: latitude,
));
}
},
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
backgroundColor: Colors.transparent,
child: _buildWidget(context)),
);
}
同时删除 postWithLocation
中的一些代码。
void postWithLocation(context) {
BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
}