Andrea Grippi
Andrea Grippi

Reputation: 1589

Flutter map_view center to user location

I'm using the map_view plugin to build a map in my Fluter app. I'm following the example, but I would like to initialize the map to the user current location without hardcoding the coordinates.

I have been digging into the docs and the Github issues and found this, but I can't understand how to apply it.

The map is initialized this way:

mapView.show(
    new MapOptions(
        mapViewType: MapViewType.normal,
        showUserLocation: true,
        initialCameraPosition: new CameraPosition(
            new Location(45.5235258, -122.6732493), 14.0),
        title: "Recently Visited"),
    toolbarActions: [new ToolbarAction("Close", 1)]);

Get notified when the map is ready

How can I use this code to set the position of the map?

mapView.onLocationUpdated.listen((location) => myUserLocation = location);

This is the entirety of my code:

Location myUserLocation = null;

class NuMapView extends StatefulWidget {
  @override
_NuMapViewState createState() => new _NuMapViewState();
}




class _NuMapViewState extends State<NuMapView> {
  static String apiKey = "mykey";

  MapView mapView;
  CameraPosition cameraPosition;
  var compositeSubscription = new CompositeSubscription();
  var staticMapProvider = new StaticMapProvider(apiKey);
  Uri staticMapUri;




  @override
  void initState(){
      print("dentro init state\n");

  mapView = new MapView();
  mapView.onLocationUpdated.listen((location) {
    print("cacchissime\n");
    if (myUserLocation == null){
      print("user location non null\n");
      myUserLocation = location;
      showMap();
    }
    else {
      print("user location è nullo!!\n");
    }


  } );

  super.initState();
    }



    bool ready = false;

  List<Marker> _markers = new List<Marker>();


    });
  }





  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Text("ciao")
      ),

    );
  }

  showMap() {
    mapView.show(
        new MapOptions(
            mapViewType: MapViewType.normal,
            showUserLocation: true,
            showMyLocationButton: true,
            showCompassButton: true,
            initialCameraPosition: new CameraPosition(
                new Location(myUserLocation.latitude, myUserLocation.longitude), 35.0),
            hideToolbar: false,
            title: "Cerca sulla mappa"),

        );
    StreamSubscription sub = mapView.onMapReady.listen((_) {
      mapView.setMarkers(_markers);

    });
    compositeSubscription.add(sub);
    sub = mapView.onLocationUpdated.listen((location) {
      print("Location updated $location");
    });
    compositeSubscription.add(sub);
    sub = mapView.onTouchAnnotation
        .listen((annotation) => print("annotation ${annotation.id} tapped"));
    compositeSubscription.add(sub);

    sub = mapView.onCameraChanged.listen((cameraPosition) =>
        this.setState(() => this.cameraPosition = cameraPosition));
    compositeSubscription.add(sub);


  }

Upvotes: 3

Views: 10205

Answers (3)

Daniele Angelini
Daniele Angelini

Reputation: 93

i found a solution using GeoLocator plugin... try this code..

  _animateToUser() async {
    Geolocator().getCurrentPosition().then((currloc) {
      setState(() {
        currentLocation = currloc;
      });
    });

    mapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
      target: LatLng(currentLocation.latitude, currentLocation.longitude),
      zoom: 17.0,
    )));
  }

in google maps part...

Stack(
  children: <Widget>[
    GoogleMap(
      initialCameraPosition: CameraPosition(target: LatLng(currentLocation.latitude, currentLocation.longitude), zoom: 17),
      onMapCreated: _onMapCreated,
      myLocationEnabled: true,
      mapType: _currentMapType,
      markers: Set<Marker>.of(markers.values),
    ),
  ],
);

hope than helps!

Upvotes: 0

AnasSafi
AnasSafi

Reputation: 6224

This code what you need (I have displayed the full code so you can try it directly):

Note, you need to install google_maps_flutter and location and permission packages to project before run this code.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:permission/permission.dart';

void main() => runApp(TestMap());

class TestMap extends StatefulWidget {
  @override
  _TestMapState createState() => _TestMapState();
}

class _TestMapState extends State<TestMap> {
  @override
  Widget build(BuildContext context) {
    //To Require Permission
    Permission.openSettings;

    return MaterialApp(
      title: 'Flutter Google Maps Demo',
      home: MapSample(),
    );
  }
}

class MapSample extends StatefulWidget {
  @override
  State<MapSample> createState() => MapSampleState();
}

class MapSampleState extends State<MapSample> {
  Map<PolylineId, Polyline> _mapPolylines = {};
  int _polylineIdCounter = 1;

  static double latitude_current = 31.9414246;
  static double longitude_current = 35.8880857;

  void _GetDeviceLocation() async {
    var location = new Location();
    location.changeSettings(
      accuracy: LocationAccuracy.HIGH,
      distanceFilter: 0,
      interval: 100,
    );
    location.onLocationChanged().listen((LocationData currentLocation) {
      latitude_current = currentLocation.latitude;
      longitude_current = currentLocation.longitude;
      _goToTheLake();
    });
  }



  Completer<GoogleMapController> _controller = Completer();

  static final CameraPosition _kLake = CameraPosition(
      bearing: 60.8334901395799,
      target: LatLng(latitude_current, longitude_current),
      tilt: 80.440717697143555,
      zoom: 18.151926040649414);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text("Maps"),
        actions: <Widget>[IconButton(icon: Icon(Icons.add), onPressed: _GetDeviceLocation)],
      ),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: CameraPosition(
          target: LatLng(latitude_current, longitude_current),
          zoom: 14.4746,
        ),
        onMapCreated: (GoogleMapController controller) async {
          _GetDeviceLocation();
          _controller.complete(controller);
        },
        myLocationEnabled: true,
        polylines: Set<Polyline>.of(_mapPolylines.values),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _goToTheLake,
        label: Text('Drive Mode'),
        icon: Icon(Icons.directions_boat),
      ),
    );
  }

  Future<void> _goToTheLake() async {
    _GetDeviceLocation();
    final GoogleMapController controller = await _controller.future;
    controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));

  }
}

Upvotes: 3

diegoveloper
diegoveloper

Reputation: 103351

Ok, based on the information that you posted, you can do something like this:

  //state class variable    
  Location myUserLocation;


      @override
      void initState() {
         mapView.onLocationUpdated.listen((location) {
            if (myUserLocation == null){
                myUserLocation = location;
                _loadMap();
            }

         } );
        super.initState();
      }


      _loadMap(){
          mapView.show(
           new MapOptions(
              mapViewType: MapViewType.normal,
              showUserLocation: true,
              initialCameraPosition: new CameraPosition(
                  new Location(myUserLocation.latitude, myUserLocation.longitude), 14.0),
              title: "Recently Visited"),
          toolbarActions: [new ToolbarAction("Close", 1)]);
      }

First, after initState you can get your current location and call showMap with your location.

Upvotes: 3

Related Questions