Ошибка при передаче широты и долготы в Latlng во флаттере

Я пытаюсь реорганизовать свой код и разделил класс showMap на новый файл dart. Я передаю широту и долготу с экрана, на котором этот класс вызывается для showMap. Я проверил, что широта и долгота здесь не равны нулю. Но я получаю сообщение об ошибке:

The following NoSuchMethodError was thrown building showMap(dirty): The method 'compareTo' was called on null. Receiver: null Tried calling: compareTo(-90.0)

class showMap extends StatelessWidget {
  showMap({this.latitude, this.longitude});
  double latitude;
  double longitude;

  @override
  Widget build(BuildContext context) {
    return FlutterMap(
      options: MapOptions(
        center: LatLng(latitude, longitude), // The Error line
        zoom: 16.0,
      ),
      layers: [
        TileLayerOptions(
            urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
            subdomains: ['a', 'b', 'c']),
        MarkerLayerOptions(
          markers: [
            Marker(
              width: 80.0,
              height: 80.0,
              point: LatLng(58.7041, 37.1025),
              builder: (ctx) => GestureDetector(
                child: Container(
                  child: Icon(
                    Icons.location_on,
                    size: 60,
                    color: Color(0xFF744D81),
                  ),
                ),
                onTap: () {
                  showModalBottomSheet(
                      context: context,
                      builder: (context) {
                        return MarkerPopup();
                      });
                },
              ),
            ),
            Marker(
              width: 80.0,
              height: 80.0,
              point: LatLng(58.4419, 37.0784),
              builder: (ctx) => GestureDetector(
                child: Container(
                  child: Icon(Icons.location_on,
                      size: 60, color: Color(0xFF744D81)),
                ),
                onTap: () {
                  showModalBottomSheet(
                      context: context,
                      builder: (context) {
                        return MarkerPopup();
                      });
                },
              ),
            ),
          ],
        ),
      ],
    );
  }
}

Вот часть кода, в которой вызывается showMap:

class _HomePageState extends State<HomePage> {

  void getLocation() async {
    Location location = Location();
    await location.getCurrrentLocation();
    latitude = location.latitude;
    longitude = location.longitude;
  }

  @override
  void initState() {
    super.initState();
    getLocation();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Udan'),
        backgroundColor: Color(0xFF4E295B),
        centerTitle: true,
      ),
      
      body: Stack(
        children: <Widget>[
          showMap(
            latitude: latitude,
            longitude: longitude,
          ),
        ],
      ),
    );
  }
}


Особенность в том, что через секунду-две ошибка исчезает и карта загружается в правильный центр. Но пока что код ломается, и на экране отображается ошибка. Я предполагаю, что это связано с тем, что для получения местоположения требуется время, а нулевые значения широты и долготы передаются до тех пор, пока местоположение не будет получено. Я уже использовал async await на исходном экране перед присвоением значения showMap. Как мне заставить это работать? Спасибо.


person avish    schedule 13.03.2021    source источник
comment
Не могли бы вы предоставить код, в котором вызывается showMap?   -  person MindStudio    schedule 13.03.2021
comment
@MindStudio Я обновил вопрос кодом, из которого вызывается showMap. Надеюсь, это поможет немного лучше понять ситуацию.   -  person avish    schedule 13.03.2021


Ответы (2)


Метод getLocation содержит асинхронную операцию, и метод сборки выполняется до ее разрешения.

Возможным вариантом может быть отображение загрузчика, когда широта и долгота равны нулю. После разрешения будущего location.getCurrrentLocation вы можете вызвать showMap.

person glavigno    schedule 14.03.2021

showMap() вызывается до того, как появятся какие-либо данные о местоположении. Вам следует дождаться данных о местоположении, а затем построить карту с этими данными. Это можно сделать с помощью FutureBuilder:

Во-первых, вы должны создать будущее.

Future<Location> getLocation = Future<Location>() async {
    Location location = new Location();
    var serviceEnabled = await location.serviceEnabled();
    if (!serviceEnabled) {
      serviceEnabled = await location.requestService();
      if (!serviceEnabled) {
        return null;
      }
    }
    var currentLocation = await location.getLocation();
    return currentLocation;
  }

Затем верните FutureBuilder вместо showMap ():

FutureBuilder<Location>(
        future: getLocation(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return showMap(latitude: snapshot.data.latitude, longitude: snapshot.data.longitude);
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        });

Я не могу проверить свой код, так как не могу заставить работать пакет местоположения. Если вы обнаружите какие-либо ошибки, я с радостью отредактирую свой ответ.

person MindStudio    schedule 14.03.2021