map_latlng_picker 1.0.3 copy "map_latlng_picker: ^1.0.3" to clipboard
map_latlng_picker: ^1.0.3 copied to clipboard

A beautiful Google Maps location latitude and longitude picker with physics-based animations. Features an animated pin with bounce effects, elevation, and haptic feedback.

LatLng Picker #

A beautiful Flutter package that provides an interactive location latitude and longitude picker with physics-based animations for Google Maps. Pick locations with style using an animated pin that bounces and elevates with realistic physics.

LatLng Picker Demo

What is it? #

LatLng Picker is a wrapper widget for Google Maps Flutter that adds an intuitive latitude and longitude picking experience. Instead of placing markers, users can pan the map while a fixed center pin shows where they're selecting. The pin features smooth animations with:

  • Fixed center positioning
  • Physics-based bounce effects
  • Elevation animations with dynamic shadows
  • Haptic feedback
  • Fully customizable appearance

Under the Hood #

This package uses:

  • google_maps_flutter - The official Google Maps plugin for Flutter
  • Flutter's Animation Framework - For smooth, physics-based pin animations
  • Custom AnimationControllers - To orchestrate bounce, stretch, and shadow effects

How to Use #

Installation #

Add to your pubspec.yaml:

dependencies:
  map_latlng_picker: ^1.0.3
  google_maps_flutter: ^2.14.0

Google Maps API Key Setup #

Before using this package, you need to configure Google Maps API keys for your target platforms:

🌐 Web

Add to web/index.html:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_HERE"></script>

πŸ€– Android

Add to android/app/src/main/AndroidManifest.xml inside <application>:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY_HERE"/>

🍎 iOS

In ios/Runner/AppDelegate.swift:

import GoogleMaps

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    GMSServices.provideAPIKey("YOUR_API_KEY_HERE")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

πŸ“š Get your Google Maps API key

Basic Usage #

Simply wrap your GoogleMap widget with LatLngLocationPicker:

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:map_latlng_picker/map_latlng_picker.dart';

class LocationPickerScreen extends StatefulWidget {
  @override
  State<LocationPickerScreen> createState() => _LocationPickerScreenState();
}

class _LocationPickerScreenState extends State<LocationPickerScreen> {
  final LatLngLocationPickerController _controller = LatLngLocationPickerController();
  LatLng? _selectedLocation;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Pick Location')),
      body: LatLngLocationPicker(
        controller: _controller,
        enabled: true,
        onLocationPicked: (location) {
          setState(() {
            _selectedLocation = location;
          });
          print('Selected: ${location.latitude}, ${location.longitude}');
        },
        child: GoogleMap(
          initialCameraPosition: CameraPosition(
            target: LatLng(37.7749, -122.4194),
            zoom: 14,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _controller.isEnabled
            ? _controller.disable?.call()
            : _controller.enable?.call();
        },
        child: Icon(_controller.isEnabled ? Icons.check : Icons.location_on),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

Advanced Usage with Custom Pin #

LatLngLocationPicker(
  enabled: true,
  pinOffset: 60,
  useHapticFeedback: true,
  onLocationPicked: (location) {
    // Handle picked location
  },
  pinWidget: AnimatedLocationPin(
    state: _isPanning ? PinState.elevated : PinState.idle,
    color: Colors.blue,
    innerColor: Colors.white,
    size: 50,
    stickHeight: 25,
    shadowDistance: 20,
  ),
  child: GoogleMap(
    initialCameraPosition: CameraPosition(
      target: LatLng(37.7749, -122.4194),
      zoom: 14,
    ),
  ),
)

Simplified Pin Customization with AnimatePinData #

LatLngLocationPicker(
  enabled: true,
  pinData: AnimatePinData(
    color: Colors.blue,
    innerColor: Colors.white,
    stickColor: Colors.blueAccent,
    size: 50,
    stickHeight: 25,
    stickBorderRadius: 4.0,
    shadowColor: Colors.black54,
    shadowDistance: 10.0,
  ),
  onLocationPicked: (location) {
    // Handle picked location
  },
  child: GoogleMap(
    initialCameraPosition: CameraPosition(
      target: LatLng(37.7749, -122.4194),
      zoom: 14,
    ),
  ),
)

Parameters #

LatLngLocationPicker #

Parameter Type Default Description
child Widget required The GoogleMap widget to wrap
controller LatLngLocationPickerController? null Controller to enable/disable picker programmatically
onLocationPicked OnLatLngLocationPicked? null Callback fired when user releases the map
pinWidget Widget? null Custom pin widget (uses AnimatedLocationPin by default)
pinData AnimatePinData? null Pin customization data (alternative to pinWidget)
pinOffset double 50 Vertical offset from center (useful for pins with bottom pointer)
enabled bool false Whether location picker is enabled by default
useHapticFeedback bool true Enable haptic feedback on pan start/end

AnimatePinData #

Parameter Type Default Description
state PinState? null Advanced mode: Control pin state
isElevated bool false Simple mode: Whether pin is elevated
color Color required Main circle color
innerColor Color required Inner dot color
stickColor Color? null Stick color (defaults to main color)
stickWidth double? null Stick width (defaults to 15% of size)
stickBorderRadius double 4.0 Border radius of the stick
shadowColor Color required Shadow color
size double 40.0 Pin size (circle diameter)
stickHeight double 20.0 Height of the stick
shadowDistance double 10.0 Shadow distance when elevated (advanced mode)
duration Duration Duration(milliseconds: 300) Animation duration

AnimatedLocationPin #

Parameter Type Default Description
state PinState? null Advanced mode: Control pin state (idle/elevated)
isElevated bool false Simple mode: Whether pin is elevated
color Color Colors.red Main circle color
innerColor Color Colors.white Inner dot color
stickColor Color? null Stick color (defaults to main color)
stickWidth double? null Stick width (defaults to 10% of size)
stickBorderRadius double 12 Border radius of the stick
shadowColor Color Colors.black26 Shadow color
size double 40 Pin size (circle diameter)
stickHeight double 20 Height of the stick
shadowDistance double 15 Shadow distance when elevated (advanced mode)
duration Duration Duration(milliseconds: 200) Animation duration (simple mode)

LatLngLocationPickerController #

Method/Property Type Description
enable() VoidCallback? Enable location picking mode
disable() VoidCallback? Disable location picking mode
isEnabled bool Get current enabled state
dispose() void Clean up controller resources

Pin Animation Modes #

Simple Mode (Boolean) #

Use isElevated for basic on/off elevation:

AnimatedLocationPin(
  isElevated: _isPanning,
)

Advanced Mode (PinState) #

Use state for enhanced animations with smoother transitions:

AnimatedLocationPin(
  state: _isPanning ? PinState.elevated : PinState.idle,
)

Examples #

Example 1: Basic Location Picker #

LatLngLocationPicker(
  enabled: true,
  onLocationPicked: (location) {
    print('Location: ${location.latitude}, ${location.longitude}');
  },
  child: GoogleMap(
    initialCameraPosition: CameraPosition(
      target: LatLng(0, 0),
      zoom: 10,
    ),
  ),
)

Example 2: With Controller #

final controller = LatLngLocationPickerController();

// Enable picker
controller.enable?.call();

// Disable picker
controller.disable?.call();

// Check state
if (controller.isEnabled) {
  // Picker is active
}

Example 3: Custom Styled Pin #

LatLngLocationPicker(
  enabled: true,
  pinWidget: AnimatedLocationPin(
    isElevated: _isPanning,
    color: Colors.purple,
    innerColor: Colors.yellow,
    size: 60,
    stickHeight: 30,
    stickBorderRadius: 4,
  ),
  child: GoogleMap(
    initialCameraPosition: CameraPosition(
      target: LatLng(37.7749, -122.4194),
      zoom: 14,
    ),
  ),
)

Example 4: Using AnimatePinData #

LatLngLocationPicker(
  enabled: true,
  pinData: AnimatePinData(
    color: Colors.green,
    innerColor: Colors.white,
    stickColor: Colors.greenAccent,
    size: 55,
    stickHeight: 28,
    stickBorderRadius: 6.0,
    shadowColor: Colors.black45,
    shadowDistance: 12.0,
  ),
  onLocationPicked: (location) {
    print('Picked: ${location.latitude}, ${location.longitude}');
  },
  child: GoogleMap(
    initialCameraPosition: CameraPosition(
      target: LatLng(37.7749, -122.4194),
      zoom: 14,
    ),
  ),
)

Features #

  • Smooth physics-based animations
  • Customizable pin appearance
  • Haptic feedback support
  • Controller for programmatic control
  • Works as a simple wrapper - no map recreation needed
  • Preserves all GoogleMap properties and callbacks
  • Two animation modes (simple boolean and advanced state-based)
  • Dynamic shadow effects

Author #

Paul Jeremiah
Twitter: @edeme_kong

Support #

If you find this package helpful, consider buying me a coffee! β˜•

Buy Me A Coffee

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

map_latlng_picker #

4
likes
160
points
1
downloads

Publisher

verified publisherthinkinteltech.com

Weekly Downloads

A beautiful Google Maps location latitude and longitude picker with physics-based animations. Features an animated pin with bounce effects, elevation, and haptic feedback.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, google_maps_flutter

More

Packages that depend on map_latlng_picker