Ошибка поздней инициализации: поле «Инициализация» не было инициализировано

#flutter #google-maps #dart

Вопрос:

Я пытаюсь создать экран карты, но обнаружил следующую ошибку:

 ======== Exception caught by widgets library =======================================================
The following LateError was thrown building Consumer<MapViewModel>(dirty, dependencies: [_InheritedProviderScope<MapViewModel>]):
LateInitializationError: Field 'initialPosition' has not been initialized.

The relevant error-causing widget was: 
  Consumer<MapViewModel> file:///Users/mahmoudalharoon/Desktop/Air Forces/aireforces/lib/screens/BaseScreen.dart:44:14
When the exception was thrown, this was the stack: 
#0      MapViewModel.initialPosition (package:airforces/screens/map/viewmodel/map_viewmodel.dart)
#1      MapScreen.build.<anonymous closure> (package:airforces/screens/map/view/map_screen.dart:19:27)
#2      Consumer.buildWithChild (package:provider/src/consumer.dart:180:19)
#3      SingleChildStatelessWidget.build (package:nested/nested.dart:259:41)
#4      StatelessElement.build (package:flutter/src/widgets/framework.dart:4648:28)
...
====================================================================================================
 

и это ViewModel то, что у меня есть ниже:

 import 'package:airforces/enums/ScreenState.dart';
import 'package:airforces/screens/BaseViewModel.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapViewModel extends BaseViewModel {
  late LatLng? initialPosition;
  late LatLng lastMapPosition = initialPosition!;

  void getUserLocation() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    List<Placemark> placemarks = await placemarkFromCoordinates(
        position.latitude, position.longitude);
    initialPosition = LatLng(position.latitude, position.longitude);
    print('${placemarks[0].name}');
    setState(ViewState.Idle);
  }
}
 

и это экран карты ниже, который у меня есть:

 import 'package:airforces/screens/BaseScreen.dart';
import 'package:airforces/screens/map/viewmodel/map_viewmodel.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return BaseScreen<MapViewModel>(
      onFinish: (_) {
      },
      onModelReady: (mapViewModel) {
        mapViewModel.getUserLocation();
      },
      builder: (context, mapViewModel, child){
        return GoogleMap(
          initialCameraPosition: CameraPosition(
            target: mapViewModel.initialPosition!,
          ),
          myLocationEnabled: true,
        );
      },
    );
  }
}
 

Ответ №1:

Проблема возникает из initialPosition null -за того, что происходит до тех пор, пока late не произойдет инициализация, но она преобразуется в тип, не допускающий значения null, до того, как произойдет поздняя инициализация здесь: mapViewModel.initialPosition! .

Вы можете решить эту проблему одним из двух способов.

  1. Верните позицию по умолчанию, если initialPosition это null при доступе к ней.
 target: mapViewModel.initialPosition ?? [defaultPosition];
 
  1. Отображение виджета загрузки до тех пор, пока initialPosition он не будет инициализирован, затем отображение GoogleMap .

Для обоих этих решений потребуется незначительное решение для управления состоянием, чтобы обновить виджет, когда initialPosition он будет окончательно инициализирован.