import 'package:flutter/material.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; import '../models/location.dart'; class LocationSelector extends StatefulWidget { final Function(MyLocation) onLocationChanged; // Callback function const LocationSelector({super.key, required this.onLocationChanged}); @override LocationSelectorState createState() => LocationSelectorState(); } class LocationSelectorState extends State { final TextEditingController _locationController = TextEditingController(); String _street = ''; String _country = ''; String? _administrativeArea; // DE: Bundesland String _city = ''; String? _subLocality; // DE: Stadtteil String? _postalCode; double? _latitude; double? _longitude; String? errorText; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( // onSubmitted: (loc) => {_searchLocation2(loc)}, controller: _locationController, decoration: InputDecoration( labelText: 'Enter location', suffixIcon: IconButton( icon: const Icon(Icons.search), onPressed: _searchLocation, ), ), ), Text( errorText != null ? '$errorText' : '', style: const TextStyle(color: Colors.red), ), const SizedBox(height: 20), ElevatedButton( onPressed: _getCurrentLocation, child: const Text('Use Current Position'), ), const SizedBox(height: 20), Text('Country: $_country'), Text('City: $_city'), Text('Postal Code: $_postalCode'), Text('Street: $_street'), Text('Administrative Area: $_administrativeArea'), Text('Latitude: $_latitude'), Text('Longitude: $_longitude'), ], ); } void _searchLocation() async { String locationQuery = _locationController.text.trim(); if (locationQuery.isEmpty) { _resetLocationData('Specify an address for the search'); return; } try { List locations = await locationFromAddress(locationQuery); if (locations.isNotEmpty) { // Take first match Location firstLocation = locations.first; // Extract country and city information List placeMarks = await placemarkFromCoordinates( firstLocation.latitude, firstLocation.longitude); if (placeMarks.isNotEmpty) { Placemark placeMark = placeMarks.first; setState(() { _latitude = firstLocation.latitude; _longitude = firstLocation.longitude; _street = '${placeMark.street}'; _country = placeMark.country!; _city = placeMark.locality!; _subLocality = placeMark.subLocality; _postalCode = placeMark.postalCode; _administrativeArea = placeMark.administrativeArea; errorText = null; }); // location is found, trigger callback triggerCallback(); } else { setState(() { // should placeMarks be empty return latitude and longitude anyway _latitude = firstLocation.latitude; _longitude = firstLocation.longitude; errorText = null; }); } } else { _resetLocationData('Location $locationQuery not found'); } } catch (e) { _resetLocationData('Error searching location $locationQuery: $e'); } } void triggerCallback(){ widget.onLocationChanged(MyLocation( street: _street, country: _country, administrativeArea: _administrativeArea, locality: _city, subLocality: _subLocality, postalCode: _postalCode, latitude: _latitude, longitude: _longitude, )); } /// Resets the location data and calls setState() void _resetLocationData(String errorMessage) { setState(() { errorText = errorMessage; _street = ''; _country = ''; _city = ''; _subLocality = null; _postalCode = null; _administrativeArea = null; _latitude = null; _longitude = null; }); } /// Determine users position using geolocator package void _getCurrentLocation() async { bool serviceEnabled; LocationPermission permission; try { // Test if location services are enabled. serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { // Location services are not enabled don't continue // accessing the position and request users of the // App to enable the location services. return Future.error('Location services are disabled.'); } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { // Permissions are denied, next time you could try // requesting permissions again (this is also where // Android's shouldShowRequestPermissionRationale // returned true. According to Android guidelines // your App should show an explanatory UI now. return Future.error('Location permissions are denied'); } } if (permission == LocationPermission.deniedForever) { // Permissions are denied forever, handle appropriately. return Future.error( 'Location permissions are permanently denied, we cannot request permissions.'); } } catch (e) { debugPrint('Error getting location permission: $e'); } try { // When we reach here, permissions are granted and we can // continue accessing the position of the device. Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high); List placeMarks = await placemarkFromCoordinates(position.latitude, position.longitude); if (placeMarks.isNotEmpty) { Placemark placeMark = placeMarks.first; setState(() { _street = placeMark.street!; _country = placeMark.country!; _city = placeMark.locality!; _latitude = position.latitude; _longitude = position.longitude; }); triggerCallback(); } } catch (e) { debugPrint('Error getting current location: $e'); } } }