Closed RedHappyLlama closed 2 years ago
Used this logic.
https://github.com/tlserver/flutter_map_location_marker/issues/11
Still has a performance issue due to stream listener.
======== Exception caught by widgets library ======================================================= The following StateError was thrown building RawGestureDetector(state: RawGestureDetectorState#b3f04(gestures: [scale, vertical drag, horizontal drag])): Bad state: Stream has already been listened to.
The relevant error-causing widget was: RawGestureDetector RawGestureDetector:file:///Users/benfloyd/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_map-0.14.0/lib/src/map/flutter_map_state.dart:88:11 When the exception was thrown, this was the stack:
It works for me in this settings. The location marker show up and the map is centered to the marker.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
import 'package:latlong2/latlong.dart';
class CenterFabExample extends StatefulWidget {
@override
_CenterFabExampleState createState() => _CenterFabExampleState();
}
class _CenterFabExampleState extends State<CenterFabExample> {
late CenterOnLocationUpdate _centerOnLocationUpdate;
late StreamController<double?> _centerCurrentLocationStreamController;
@override
void initState() {
super.initState();
_centerOnLocationUpdate = CenterOnLocationUpdate.always;
_centerCurrentLocationStreamController = StreamController<double?>();
}
@override
void dispose() {
_centerCurrentLocationStreamController.close();
super.dispose();
}
bool _isShowLocMarker = false;
@override
Widget build(BuildContext context) {
return Stack(
children: [
FlutterMap(
options: MapOptions(
center: LatLng(0, 0),
zoom: 1,
maxZoom: 19,
// Stop centering the location marker on the map if user interacted with the map.
onPositionChanged: (MapPosition position, bool hasGesture) {
if (hasGesture) {
setState(
() => _centerOnLocationUpdate = CenterOnLocationUpdate.never,
);
}
},
),
children: [
TileLayerWidget(
options: TileLayerOptions(
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: ['a', 'b', 'c'],
maxZoom: 19,
),
),
if (_isShowLocMarker)
LocationMarkerLayerWidget(
plugin: LocationMarkerPlugin(
centerCurrentLocationStream:
_centerCurrentLocationStreamController.stream,
centerOnLocationUpdate: _centerOnLocationUpdate,
),
),
],
),
Positioned(
right: 20,
bottom: 80,
child: Column(
children: [
FloatingActionButton(
heroTag: null,
onPressed: () => setState(() {
_isShowLocMarker = false;
_centerCurrentLocationStreamController.close();
}),
child: const Icon(
Icons.gps_off,
color: Colors.white,
),
),
const SizedBox(height: 20),
FloatingActionButton(
heroTag: null,
onPressed: () {
// Automatically center the location marker on the map when location updated until user interact with the map.
setState(() {
if (!_isShowLocMarker) {
_centerCurrentLocationStreamController =
StreamController<double>();
}
_centerOnLocationUpdate = CenterOnLocationUpdate.once;
_isShowLocMarker = true;
});
// Center the location marker on the map and zoom the map to level 18.
_centerCurrentLocationStreamController.add(18);
},
child: const Icon(
Icons.my_location,
color: Colors.white,
),
),
],
),
),
],
);
}
}
https://user-images.githubusercontent.com/8895426/152629866-e056ae4d-033a-4b69-9715-b8ba2a7b84cb.mp4
Hi,
Thanks! I wasn't closing the old stream and opening a new one.
Hi,
I have a very similar set up to one of the example apps: https://github.com/tlserver/flutter_map_location_marker/blob/master/example/lib/page/center_fab_example.dart
However, if the map page is loaded when location permissions are denied, tapping the FAB encourages the user to change the user permissions in the settings.
The issue is; if the user then grants location permissions, once the location is retrieved, the location marker doesn't show and the screen isn't centred on location.
if (phoneLocation.error) { APIResponse<bool> _locationServiceActive = await locationService.checkLocationService(); if (_locationServiceActive.data) { phoneLocation = await locationService.getCurrentLocation(); setState(() => _centerOnLocationUpdate = CenterOnLocationUpdate.always); _centerCurrentLocationStreamController.add(17);
Thanks!