在Flutter中请求位置时,BLoC不会产生状态 [英] BLoC does not yield state when requesting for a location in Flutter
问题描述
我正在使用三个Flutter软件包来实现一项功能,用户可以通过该软件包进行刷新,使用BLoC逻辑检索地理坐标并将其传递回Flutter。
There's three Flutter packages I am using to implement a functionality whereby a user pulls to refresh, a geo-coordinate is retrieved using BLoC logic and passed back to Flutter.
- Pull to Refresh
- BLoC
- Geolocator
麻烦的是,我无法获得BLoC在我拉动刷新中调度呼叫时产生返回结果。
Trouble is, I cannot get the BLoC to yield the return result when I dispatch a call in pull-to-refresh.
geolocation_bloc.dart
class GeolocationBloc extends Bloc<GeolocationEvent, GeolocationState> {
@override
GeolocationState get initialState => GeolocationUninitialized();
@override
Stream<GeolocationState> mapEventToState(GeolocationEvent event) async* {
if (event is RequestLocation) {
yield* _mapGeolocationRequestLocation();
}
}
Stream<GeolocationState> _mapGeolocationRequestLocation() async* {
Position position;
position = await Geolocator().getCurrentPosition();
print("RETRIEVED LOCATION"); // I CAN REACH HERE EVERYTIME.
if (position == null) {
yield LocationLoaded(0, 0);
} else {
yield LocationLoaded(position.latitude, position.longitude);
}
}
检索地理坐标。如果传感器已关闭/损坏,则返回(0,0)。
Retrieves a geo-coordinate. If sensor is off/broken, return (0,0) instead.
feed_page.dart
@override
void initState() {
super.initState();
_geolocationBloc.dispatch(RequestLocation());
}
void _onRefresh() {
_geolocationBloc.dispatch(RequestLocation());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Username')),
body: BlocProviderTree(
blocProviders: [
BlocProvider<PostBloc>(bloc: _postBloc),
BlocProvider<GeolocationBloc>(bloc: _geolocationBloc),
],
child: BlocListenerTree(
blocListeners: [
BlocListener<GeolocationEvent, GeolocationState>(
bloc: _geolocationBloc,
listener: (BuildContext context, GeolocationState state) {
if (state is LocationLoaded) {
print('LOADED'); // THIS NEVER GETS PRINTED WHEN PULLED TO REFRESH.
lat = state.latitude;
long = state.longitude;
}
..
驱动程序类调度请求 Re questLocation()
在 initState()
中一次,每次调用 onRefresh()
时。
The driver class dispatches a request RequestLocation()
once in initState()
and every time onRefresh()
is called.
但是,第一次调用 RequestLocation()
时,它已成功通过,即 initState()
,随后使用 pull-to-refresh onRefresh()
方法进行的调用似乎不会产生 LocationLoaded()
状态。
However, while the first time RequestLocation()
is called it is passes successfully i.e. in initState()
, subsequent calls using the pull-to-refresh onRefresh()
method does not seem to yield the LocationLoaded()
state.
日志
Restarted application in 2,849ms.
I/flutter ( 6125): AppStarted
I/flutter ( 6125): RequestLocation
I/flutter ( 6125): RETRIEVED LOCATION
I/flutter ( 6125): Transition { currentState: GeolocationUninitialized, event: RequestLocation, nextState: LocationLoaded { latitude: 37.4219983, longitude: -122.084} }
I/flutter ( 6125): LOCATION LOADED
I/flutter ( 6125): RequestLocation
I/flutter ( 6125): RETRIEVED LOCATION
根据日志,第一个调用会同时打印已获取位置和已加载位置,但在第二个已获取位置之后没有其他任何反应。
As per the log, the first call prints both RETRIEVED LOCATION and LOCATION LOADED, but nothing else occurs after the second RETRIEVED LOCATION.
如何解决此问题,以使刷新刷新将成功调用BLoC逻辑,该逻辑又返回具有适当坐标的 LocationLoaded()
对象。
How can I fix this such that the pull to refresh will successfully call on the BLoC logic which in turn return a LocationLoaded()
object with the appropriate coordinates.
推荐答案
我设法通过从<$ c $中删除 Equatable
继承来解决此问题c>状态和 Event
BLoC类。 Equatable
实现相等性检查导致BlocListener没有短路到相应的if / else块:
I managed to solve this by removing the Equatable
inheritance from my State
and Event
BLoC classes. Equatable
implementation of equality checking resulted in the BlocListener not short-circuiting to the corresponding if/else block:
i.e. if (state is LocationLoaded)..
在 Equatable
,或者由于我在状态(纬度/经度)中传递了两个坐标,因此导致相等性检查失败。
There is a possibility that the equality check is stricter in Equatable
or since I'm passing two coordinates in the state (Latitude/Longitude), it causes the equality check to fail.
状态类:
@immutable
abstract class GeolocationState extends Equatable { // Remove inheritance.
}
class LocationLoaded extends GeolocationState {
}
class GeolocationUninitialized extends GeolocationState {
}
这篇关于在Flutter中请求位置时,BLoC不会产生状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!