191 lines
5.8 KiB
Dart
191 lines
5.8 KiB
Dart
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<MapContent> createState() => _MapContentState();
|
|
}
|
|
|
|
class _MapContentState extends State<MapContent> {
|
|
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<void> _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),
|
|
),
|
|
);
|
|
}
|
|
}
|