получить местоположение с помощью геолокации и провайдера и flutter_maps - PullRequest
1 голос
/ 15 апреля 2020

Я пытаюсь получить текущее местоположение пользователя с помощью плагина geolocator, и я использую пакет провайдера для обработки состояния. Но я получаю сообщение об ошибке «исходное местоположение равно нулю». Я использую пакет flutter_maps, а не карты Google.

Я пытался найти решение с помощью пакета поставщика, но не нашел ни одного.

Вот мой код:

main.dart:

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';

import './maps_module/map_states.dart';
import 'home_page.dart';


void main() {
  WidgetsFlutterBinding.ensureInitialized();
  return runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: AppState())
      ],
      child: MyApp(),
    )
  );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

home_page.dart:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:latlong/latlong.dart';
import 'package:geolocator/geolocator.dart';

import './maps_module/map_states.dart';
import './maps_module/maps_screen.dart';


class HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    final appState = Provider.of<AppState>(context);

    return Scaffold(
      body: appState.initialPosition == null?
      Center(
        child: CircularProgressIndicator(),
      )
      :MapScreen(),
    );
  }
}

map_screen.dart:

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';

import 'map_states.dart';


class MapScreen extends StatefulWidget {
  @override
  _MapScreenState createState() => new _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {

  @override
  Widget build(BuildContext context) {

    final appState = Provider.of<AppState>(context);

    return SafeArea(
      child: Scaffold(
        // appBar: AppBar(),
        body: FlutterMap(
          mapController: appState.mapController,
          options: MapOptions(
            center: LatLng(appState.initialPosition.latitude, appState.initialPosition.longitude),
            minZoom: 10.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: appState.initialPosition,
                  builder: (context) =>
                  Container(
                    child: IconButton(
                      icon: Icon(Icons.location_on),
                      color: Colors.redAccent,
                      iconSize: 45.0,
                      onPressed: (){print("hey");}
                    ),
                  )
                )
              ]
            )
          ],
        ),
      )
    );
  }
}

map_states:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';


class AppState with ChangeNotifier {

  bool locationServiceActive = true;

  MapController _mapController;
  MapController get mapController => _mapController;

  static var _initialPosition;
  var _lastPosition = _initialPosition;
  LatLng get initialPosition => _initialPosition;
  LatLng get lastPosition => _lastPosition;

  AppState(){
    checkGPS();
    _getUserLocation();
  }


  checkGPS() async{
    bool conn = await Geolocator().isLocationServiceEnabled();
    if(conn == false){
      locationServiceActive = false;
    } else {
      locationServiceActive = true;
    }
    notifyListeners();
  }

  void _getUserLocation() async{
    Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    print("/////////////////////////////////////////////////////////////////////////////////position");
    print(position);

    _initialPosition = LatLng(position.latitude, position.longitude);
    notifyListeners();
  }
}

1 Ответ

1 голос
/ 15 апреля 2020

Ваша проблема в том, что вам нужно await checkgps() и _getUserLocation() в конструкторе вашего класса, проблема в том, что вы не можете запускать асинхронные функции из конструктора класса, поэтому вам нужно сделать что-то подобное , Прежде всего вам нужно удалить void из _getUserLocation() или сделать его Future<void>, затем добавить.

//Add to your class 
initalization() async {
    await _checkGPS();
    await getUserLocation();
  }

//This in a widget will prove it works
 @override
  void initState() {
    AppState().initalization();
    print('Location ${AppState().initialPosition}');
    super.initState();
  }
...