diff --git a/flutter_map/lib/flutter_map.dart b/flutter_map/lib/flutter_map.dart index f9b630765..267b5fc2b 100644 --- a/flutter_map/lib/flutter_map.dart +++ b/flutter_map/lib/flutter_map.dart @@ -14,12 +14,31 @@ export 'src/layer/polyline_layer.dart'; export 'src/map/map.dart'; class FlutterMap extends StatefulWidget { + /// A set of layers' options to used to create the layers on the map + /// + /// Usually a list of [TileLayerOptions], [MarkerLayerOptions] and + /// [PolylineLayerOptions]. final List layers; + + /// [MapOptions] to create a [MapState] with + /// + /// Please note: If both [options] and [mapState] are set, mapState's options + /// will take precedence, but the [:onTap:] callback of the options will be + /// used! final MapOptions options; - FlutterMap({this.options, this.layers}); - State createState() { - return new _FlutterMapState(); - } + + /// A [MapState], used to control the map + final MapState mapState; + + FlutterMap({ + Key key, + this.options, + this.layers, + this.mapState, + }) + : super(key: key); + + _FlutterMapState createState() => new _FlutterMapState(); } class _FlutterMapState extends MapGestureMixin { @@ -28,7 +47,18 @@ class _FlutterMapState extends MapGestureMixin { initState() { super.initState(); - mapState = new MapState(options); + mapState = widget.mapState ?? new MapState(options); + } + + void didUpdateWidget(FlutterMap oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.mapState != oldWidget.mapState) { + final MapState newMapState = widget.mapState ?? new MapState(options); + if (newMapState == mapState) return; + if (mapState != null) mapState.dispose(); + mapState = newMapState; + } } Widget build(BuildContext context) { diff --git a/flutter_map/lib/src/map/map.dart b/flutter_map/lib/src/map/map.dart index 5b1482f11..b1710a464 100644 --- a/flutter_map/lib/src/map/map.dart +++ b/flutter_map/lib/src/map/map.dart @@ -38,7 +38,9 @@ class MapState { final MapOptions options; final StreamController _onMoveSink; - double zoom; + double _zoom; + double get zoom => _zoom; + LatLng _lastCenter; Point _pixelOrigin; bool _initialized = false; @@ -52,7 +54,7 @@ class MapState { Point get size => _size; set size(Point s) { _size = s; - _pixelOrigin = getNewPixelOrigin(this._lastCenter); + _pixelOrigin = getNewPixelOrigin(_lastCenter); if (!_initialized) { _init(); _initialized = true; @@ -62,18 +64,22 @@ class MapState { LatLng get center => getCenter() ?? options.center; void _init() { - this.zoom = options.zoom; + _zoom = options.zoom; move(options.center, zoom); } + void dispose() { + _onMoveSink.close(); + } + void move(LatLng center, double zoom, [data]) { if (zoom == null) { - zoom = this.zoom; + zoom = _zoom; } - this.zoom = zoom; - this._lastCenter = center; - this._pixelOrigin = this.getNewPixelOrigin(center); + _zoom = zoom; + _lastCenter = center; + _pixelOrigin = getNewPixelOrigin(center); _onMoveSink.add(null); } @@ -86,14 +92,14 @@ class MapState { Point project(LatLng latlng, [double zoom]) { if (zoom == null) { - zoom = this.zoom; + zoom = _zoom; } return options.crs.latLngToPoint(latlng, zoom); } LatLng unproject(Point point, [double zoom]) { if (zoom == null) { - zoom = this.zoom; + zoom = _zoom; } return options.crs.pointToLatLng(point, zoom); } @@ -107,13 +113,13 @@ class MapState { } double getZoomScale(double toZoom, double fromZoom) { - var crs = this.options.crs; - fromZoom = fromZoom == null ? this.zoom : fromZoom; + var crs = options.crs; + fromZoom = fromZoom == null ? _zoom : fromZoom; return crs.scale(toZoom) / crs.scale(fromZoom); } Bounds getPixelWorldBounds(double zoom) { - return options.crs.getProjectedBounds(zoom == null ? this.zoom : zoom); + return options.crs.getProjectedBounds(zoom == null ? _zoom : zoom); } Point getPixelOrigin() { @@ -121,7 +127,7 @@ class MapState { } Point getNewPixelOrigin(LatLng center, [double zoom]) { - var viewHalf = this.size / 2; - return (this.project(center, zoom) - viewHalf).round(); + var viewHalf = _size / 2; + return (project(center, zoom) - viewHalf).round(); } }