tlserver / flutter_map_location_marker

A flutter map plugin for displaying device current location.
https://pub.dev/packages/flutter_map_location_marker
BSD 3-Clause "New" or "Revised" License
98 stars 83 forks source link

Changing `locationSettings` during runtime provided to `LocationMarkerPlugin` does not work. #13

Closed comatory closed 2 years ago

comatory commented 2 years ago

In my application I'm using Geolocator to track multiple position streams and I also use LocationSettings object that I'm sharing between different calls to Geolocator.getPositionStream.

I want to be able to sync all streams with same settings, especially distanceFilter option. I tried changing this during runtime, for example creating LocationSettings with distanceFilter=0 (default) and then switching to distanceFilter=20 so my location is not updated as frequently.

However this has no effect. Looking at the code it seems like the stream is only initialized when the plugin is created. I think it would make sense to detect that locationSettings object has changed in didUpdateWidget method and re-set the stream.

Example code:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.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 MapView extends StatefulWidget {
  const MapView({
    Key? key,
    required this.locationSettings,
    required this.permissionsEnabled,
  }) : super(key: key);

  final LocationSettings? locationSettings;
  final bool permissionsEnabled;

  @override
  _MapViewState createState() => _MapViewState();
}

class _MapViewState extends State<MapView> {
  CenterOnLocationUpdate _centerOnLocationUpdate =
      CenterOnLocationUpdate.never;
  final StreamController<double> _centerCurrentLocationStreamController =
      StreamController<double>();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey,
      child: FlutterMap(
          options: MapOptions(
            center: LatLng(50.1314, 14.50984),
            zoom: 13.0,
            onPositionChanged: (position, 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'],
                attributionBuilder: (_) {
                  return const Text("© OpenStreetMap contributors");
                },
              ),
            ),
            LocationMarkerLayerWidget(
              plugin: LocationMarkerPlugin(
                locationSettings:
                    widget.locationSettings ?? const LocationSettings(),
                centerCurrentLocationStream:
                    _centerCurrentLocationStreamController.stream,
                centerOnLocationUpdate: _centerOnLocationUpdate,
              ),
            ),
            Positioned(
              right: 20,
              bottom: 20,
              child: FloatingActionButton(
                onPressed: () {
                  // Automatically center the location marker on the map when location updated until user interact with the map.
                  setState(() => _centerOnLocationUpdate = CenterOnLocationUpdate.always);
                  // 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,
                ),
              ),
            ),
          ]),
    );
  }
}
tlserver commented 2 years ago

I just uploaded version 3.0.0 which can accept streams from application as the source. Hope that solve this problem.

comatory commented 2 years ago

I just uploaded version 3.0.0 which can accept streams from application as the source. Hope that solve this problem.

Yes I think it's better to expose the stream like you did.