import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:geolocator/geolocator.dart'; class MapContent extends StatefulWidget { const MapContent({super.key}); @override State createState() => _MapContentState(); } class _MapContentState extends State { GoogleMapController? _mapController; LatLng _initialPosition = const LatLng(48.8566, 2.3522); // Paris par défaut final TextEditingController _searchController = TextEditingController(); bool _isLoadingLocation = false; Position? _currentPosition; @override void initState() { super.initState(); _getCurrentLocation(); } @override void dispose() { _searchController.dispose(); _mapController?.dispose(); super.dispose(); } // Obtenir la position actuelle Future _getCurrentLocation() async { setState(() { _isLoadingLocation = true; }); try { // Vérifier si la localisation est activée bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { _showError('Veuillez activer les services de localisation'); setState(() { _isLoadingLocation = false; }); return; } // Vérifier les permissions LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { _showError('Permission de localisation refusée'); setState(() { _isLoadingLocation = false; }); return; } } if (permission == LocationPermission.deniedForever) { _showError('Permission de localisation refusée définitivement'); setState(() { _isLoadingLocation = false; }); return; } // Obtenir la position actuelle Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); setState(() { _currentPosition = position; _initialPosition = LatLng(position.latitude, position.longitude); _isLoadingLocation = false; }); // Animer la caméra vers la position actuelle if (_mapController != null) { _mapController!.animateCamera( CameraUpdate.newLatLngZoom(_initialPosition, 14), ); } } catch (e) { _showError('Erreur lors de la récupération de la position: $e'); setState(() { _isLoadingLocation = false; }); } } void _showError(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.red), ); } void _searchLocation() { final searchQuery = _searchController.text.trim(); if (searchQuery.isNotEmpty) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('Recherche de: $searchQuery'))); } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.all(12.0), child: Column( children: [ // Champ de recherche TextField( controller: _searchController, decoration: InputDecoration( hintText: 'Rechercher un lieu...', prefixIcon: const Icon(Icons.search), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.0), ), filled: true, fillColor: Colors.white, ), onSubmitted: (_) => _searchLocation(), ), const SizedBox(height: 12), // Google Maps Expanded( child: Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(16), child: GoogleMap( initialCameraPosition: CameraPosition( target: _initialPosition, zoom: 14, ), onMapCreated: (GoogleMapController controller) { _mapController = controller; }, myLocationEnabled: true, myLocationButtonEnabled: false, zoomControlsEnabled: false, ), ), // Indicateur de chargement if (_isLoadingLocation) Center( child: Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 8), Text('Localisation en cours...'), ], ), ), ), ], ), ), ], ), ), ), // Bouton flottant pour recentrer sur la position actuelle floatingActionButton: FloatingActionButton( onPressed: _getCurrentLocation, tooltip: 'Ma position', child: Icon(Icons.my_location), ), ); } }