Я получаю нулевое возвращаемое значение из метода. флаттер - PullRequest
0 голосов
/ 02 марта 2020

Я очень плохо знаком с Flutter / Dart и использую шаблон flutter_blo c bloc / repository.

Я изо всех сил пытаюсь получить значение из метода репозитория, и я получаю нулевое значение в методе blo c.

Часть blo c работает нормально, но ожидаемое значение LatLng Я получаю метод хранилища форм нулевой.

blo c и метод Event to State:

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);
      } 

печатает:

flutter: _mapGetLocationStreamToState () locationStream: null

flutter: Transaction is Transition {currentState: LocationStream {location: null}, событие: экземпляр GetLocationStream, nextState: LocationStream {location: null}}

Я пробовал оба T и Future<T> возвращают типы для метода репозитория, возвращая значение из разных областей (см. закомментированные результаты), но я всегда получаю нулевое значение независимо от того, откуда я возвращаю значение. Можете ли вы определить, где проблема? Должен быть в 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 (широта: 37.33022, долгота: -122.023788) flutter: getLocationStream () местоположение: LatLng (широта: 37.330219, долгота: -122.023748) flutter: getLocationStream () местоположение: LatLng (широта: 37.330219, долгота: -122.023708) flutter: 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 (широта: 37.324746, долгота : -122.021542) flutter: getLocationStream () расположение: LatLng (широта: 37.324746, долгота: -122.021573) flutter: getLocationStream () расположение: LatLng (широта: 37.324746, долгота: -122.021605)

1 Ответ

0 голосов
/ 03 марта 2020

Немного поигравшись с кодом, я решил изменить подход, и кажется, что раньше я выбрал неправильный. Вместо того, чтобы возвращать LatLng из метода репозитория, я решил преобразовать поток Stream<Position> coming from Geolocator API directly into a и прослушивать его из blo c.

Теперь состояния текут, как и ожидалось, перенося новое местоположение значение с ними.

Единственная проблема, которую осталось решить (которую я на самом деле думал, что у меня не было), это то, что 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');
    }
  }

blo c:

    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)} flutter: _mapGetLocationStreamToState () locationStream is: LatLng (широта: 37.3246, долгота: -122.02457) flutter: Transaction is Latition {currentState: LocationSt широта: 37,324603, долгота: -122. 024523)}, событие: LocationUpdated {обновленное местоположение: LatLng (широта: 37.3246, долгота: -122.02457)}, nextState: LocationStream {location: LatLng (широта: 37.3246, долгота: -122.02457)}}

...