【发布时间】:2020-06-15 02:59:13
【问题描述】:
我对 Flutter/Dart 还是很陌生,我正在使用 flutter_bloc bloc/repository 模式。
我正在努力从 bloc 方法中的存储库方法中获取值。
我的第一种方法 (I get null returned value from a method. Flutter) 是在存储库方法中收听 Stream<Position> 并返回一个 LatLng 我会在我的 bloc 方法中得到保持..我总是得到 null。
所以我的新方法是使用StreamTransformer 将Stream<Position> 转换为Stream<LatLng>,但我坚持编写存储库方法,因为.transform 似乎不可用,我得到了错误
The method 'transform' isn't defined for the class 'Function'。
你能看出我做错了什么吗?
一如既往的感谢。
我的两种方法是:
存储库:
StreamSubscription _positionStreamSubsciption;
Stream<LatLng> getLocationStream() {
print('getLocationStream() called');
print('isTracking was : $isTracking');
LatLng location;
Stream<LatLng> locationStream;
LocationOptions locationOptions = LocationOptions(
accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0);
try {
if (isTracking == true) {
_positionStreamSubsciption.cancel();
} else {
_positionStreamSubsciption = locationManager
.getPositionStream(locationOptions)
.listen((Position position) {
if (position != null) {
location = LatLng(position.latitude, position.longitude);
handleData(Position position, EventSink<LatLng> sink) =>
sink.add(location);
final transformer =
StreamTransformer<Position, LatLng>.fromHandlers(
handleData: handleData);
return _positionStreamSubsciption.onData.transform(transformer); // .transform trows an ERROR
}
print('getLocationStream() location is : $location');
});
}
isTracking = !isTracking;
print('isTracking is : $isTracking');
} catch (error) {
print('startTracking error: $error');
}
}
块:
LatLng locationStream;
StreamSubscription _locationStreamSubscription;
Stream<MapState> _mapGetLocationStreamToState(
GetLocationStream event) async* {
print('_mapGetLocationStreamToState event received : $event');
_locationStreamSubscription =
_mapRepository.getLocationStream().listen((LatLng location) {
locationStream = location;
});
更新:
在修改了一下代码后,我发现了错误所在:
在存储库中,我确实设置了一个侦听器,但需要流本身,所以我添加了
_positionStream = locationManager.getPositionStream(locationOptions);。在
StreamTransformer的handleData中,我向Stream<LatLng> locationStream添加了来自侦听器的位置,而不是从其参数Position position中获取位置。所以我把它改成了handleData(Position position, EventSink<LatLng> sink) => sink.add(LatLng(position.latitude, position.longitude));。在 bloc 中,我还必须收听来自
_mapRepository.getLocationStream()的位置流。现在,因为无法直接从侦听器范围内产生状态,而从范围外产生状态只会产生当前流值并且之后不会更新,所以我不得不使用事件循环。我向该集团添加了一个LocationUpdatedevent 从流中传递位置。在 bloc
smapEventToStateI had to react to that event yielding theLocationStream` 状态以及位置。
现在状态正在按预期流动,并带有新的位置值。
剩下要解决的唯一问题(我实际上认为我没有)是 MapScren BlocBuilder 没有获取来自新状态的值,并且在使用它时我得到 null _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');
}
}
集团:
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);
}
【问题讨论】: