import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:geolocator/geolocator.dart'; class LocationPickerResult { final LatLng position; final String address; LocationPickerResult({ required this.position, required this.address, }); } class LocationPickerScreen extends StatefulWidget { final LatLng? initialPosition; const LocationPickerScreen({ super.key, this.initialPosition, }); @override State createState() => _LocationPickerScreenState(); } class _LocationPickerScreenState extends State { late GoogleMapController _mapController; LatLng _selectedPosition = const LatLng(0, 0); Set _markers = {}; bool _isLoading = true; final String _selectedAddress = 'Selected Location'; @override void initState() { super.initState(); _initializeMap(); } Future _initializeMap() async { try { if (widget.initialPosition != null) { _selectedPosition = widget.initialPosition!; } else { final position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); _selectedPosition = LatLng(position.latitude, position.longitude); } _updateMarker(); setState(() => _isLoading = false); } catch (e) { setState(() => _isLoading = false); } } void _updateMarker() { setState(() { _markers = { Marker( markerId: const MarkerId('selected_location'), position: _selectedPosition, draggable: true, onDragEnd: (LatLng newPosition) { setState(() { _selectedPosition = newPosition; _markers = { Marker( markerId: const MarkerId('selected_location'), position: newPosition, draggable: true, ), }; }); }, ), }; }); } void _onMapCreated(GoogleMapController controller) { _mapController = controller; } Future _getCurrentLocation() async { try { final position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); final newLatLng = LatLng(position.latitude, position.longitude); setState(() => _selectedPosition = newLatLng); _updateMarker(); _mapController.animateCamera( CameraUpdate.newLatLngZoom(newLatLng, 15), ); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error getting location: $e')), ); } } } void _confirmLocation() { Navigator.pop( context, LocationPickerResult( position: _selectedPosition, address: _selectedAddress, ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Select Location'), actions: [ IconButton( icon: const Icon(Icons.my_location), onPressed: _getCurrentLocation, tooltip: 'Use current location', ), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : Column( children: [ Expanded( child: GoogleMap( onMapCreated: _onMapCreated, initialCameraPosition: CameraPosition( target: _selectedPosition, zoom: 15, ), markers: _markers, onTap: (LatLng position) { setState(() => _selectedPosition = position); _updateMarker(); }, myLocationEnabled: true, myLocationButtonEnabled: false, ), ), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 10, offset: const Offset(0, -2), ), ], ), child: SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ const Icon(Icons.location_on), const SizedBox(width: 8), Expanded( child: Text( '${_selectedPosition.latitude.toStringAsFixed(6)}, ${_selectedPosition.longitude.toStringAsFixed(6)}', style: Theme.of(context).textTheme.bodyMedium, ), ), ], ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _confirmLocation, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text('Confirm Location'), ), ), ], ), ), ), ], ), ); } }