我对Flutter / Dart非常陌生,并且正在使用flutter_bloc块/存储库模式。
我正在努力从存储库方法获取值,而在bloc方法中却得到null。
块部分工作正常,但从表单存储库方法获得的LatLng期望值为空。
bloc的值和“事件到状态”方法:
LatLng locationStream;
Stream<MapState> _mapGetLocationStreamToState(
GetLocationStream event) async* {
print('_mapGetLocationStreamToState event received : $event');
locationStream = await _mapRepository.getLocationStream();
print('_mapGetLocationStreamToState() locationStream is: $locationStream ');
yield LocationStream(locationStream);
}
打印:
颤振:_mapGetLocationStreamToState()locationStream为:null
flutter:交易正在过渡{currentState:LocationStream {location:null},事件:“ GetLocationStream”的实例,nextState: LocationStream {location:null}}
我尝试使用T
和Future<T>
的存储库方法返回类型,都从不同的范围返回值(请参见注释掉的返回值),但是无论从何处返回值,我总是得到null。
您能找出问题所在吗?
应该使用getLocation()
方法吧?
非常感谢您的时间和帮助。
T:
LatLng getLocationStream() {
print('getLocationStream() called');
LatLng location;
LocationOptions locationOptions = LocationOptions(
accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0);
try {
if (isTracking == true) {
_positionStreamSubsciption.cancel();
isTracking = !isTracking;
} else {
_positionStreamSubsciption = locationManager
.getPositionStream(locationOptions)
.listen((Position position) {
if (position != null) {
location = LatLng(position.latitude, position.longitude);
// return location; // stops the stream
}
isTracking = !isTracking;
print('getLocationStream() location is : $location');
// return location; // returns null
});
// return location; // returns null
}
// return location; // returns null
} catch (error) {
print('startTracking error: $error');
}
return location; // returns null
}
打印:
flutter:getLocationStream()的位置是:LatLng(latitude:37.33022, 经度:-122.023788)抖动:getLocationStream()的位置是: LatLng(纬度:37.330219,经度:-122.023748)抖动: getLocationStream()的位置是:LatLng(纬度:37.330219, 经度:-122.023708)抖动:getLocationStream()的位置是: LatLng(纬度:37.330221,经度:-122.023668)
未来:
Future<LatLng> getLocationStream() {
print('getLocationStream() called');
print('isTracking was : $isTracking');
Future<LatLng> location;
LocationOptions locationOptions = LocationOptions(
accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0);
try {
if (isTracking == true) {
_positionStreamSubsciption.cancel();
// isTracking = !isTracking;
// print('isTracking was ${!isTracking} and now is : $isTracking');
} else {
_positionStreamSubsciption = locationManager
.getPositionStream(locationOptions)
.listen((Position position) {
if (position != null) {
location =
LatLng(position.latitude, position.longitude) as Future<LatLng>;
// return location;
}
print('getLocationStream() location is : $location');
// return location;
});
// return location;
}
isTracking = !isTracking;
print('isTracking is : $isTracking');
// return location;
} catch (error) {
print('startTracking error: $error');
}
}
打印:
flutter:getLocationStream()的位置是:LatLng(latitude:37.324746, 经度:-122.021542)抖动:getLocationStream()位置为: LatLng(纬度:37.324746,经度:-122.021573)抖动: getLocationStream()的位置是:LatLng(latitude:37.324746, 经度:-122.021605)
答案 0 :(得分:0)
稍微摆弄代码后,我决定更改方法,似乎以前选择了错误的代码。
我决定不转换存储库方法的LatLng,而是决定转换Stream<Position> coming from
Geolocator API directly into a
Stream,并从bloc收听它。
现在状态如预期般流动,并带有新的位置值。
要解决的唯一问题(我实际上以为我没有)是MapScren
BlocBuilder
不能容纳来自新状态的值,而当像_mapController.move(userLocation, 16);
中一样使用它。
LatLng userLocation = (state as LocationStream).location;
不是正确的方法吗?
更新的代码是:
BlocBuilder:
bloc: MapBloc(mapRepository: _mapRepository),
builder: (BuildContext context, MapState state) {
LatLng userLocation = (state as LocationStream).location;
return Scaffold(
..
存储库:
Stream<LatLng> getLocationStream() {
print('getLocationStream() called');
print('isTracking was : $isTracking');
Stream<LatLng> locationStream;
Stream<Position> _positionStream;
LocationOptions locationOptions = LocationOptions(
accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0);
try {
if (isTracking == true) {
_positionStreamSubsciption.cancel();
} else {
_positionStream = locationManager.getPositionStream(locationOptions);
handleData(Position position, EventSink<LatLng> sink) =>
sink.add(LatLng(position.latitude, position.longitude));
final transformer = StreamTransformer<Position, LatLng>.fromHandlers(
handleData: handleData);
locationStream = _positionStream.transform(transformer);
return locationStream;
}
isTracking = !isTracking;
print('isTracking is : $isTracking');
} catch (error) {
print('startTracking error: $error');
}
}
bloc:
MapState get initialState => LocationStream(locationStream);
@override
Stream<MapState> mapEventToState(MapEvent event) async* {
// user location
if (event is GetLocationStream) {
print('MapBloc event received : $event');
yield* _mapGetLocationStreamToState(event);
}
if (event is LocationUpdated) {
yield* _mapLocationUpdatedToState(event);
}
}
Stream<MapState> _mapGetLocationStreamToState(
GetLocationStream event) async* {
print('_mapGetLocationStreamToState event received : $event');
_locationStreamSubscription =
_mapRepository.getLocationStream().listen((LatLng location) {
locationStream = location;
add(LocationUpdated(locationStream));
print(
'_mapGetLocationStreamToState() locationStream is: $locationStream ');
});
// yield LocationStream(locationStream);
}
控制台打印:
颤振:事件为LocationUpdated {更新位置: LatLng(纬度:37.3246,经度:-122.02457)}颤动: _mapGetLocationStreamToState()locationStream是:LatLng(纬度:37.3246,经度:-122.02457)抖动:交易记录为 Transition {currentState:LocationStream {location: LatLng(纬度:37.324603,经度:-122.024523)},事件: LocationUpdated {更新位置:LatLng(latitude:37.3246, 经度:-122.02457)},nextState:LocationStream {location: LatLng(纬度:37.3246,经度:-122.02457)}}