onLocationChanged Callback

master
Rafael 2024-05-09 21:55:17 +02:00
parent fad377ecca
commit ea81c2ea97
5 changed files with 104 additions and 37 deletions

View File

@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:cofounderella/models/location.dart';
class LocationSelector extends StatefulWidget {
const LocationSelector({super.key});
final Function(MyLocation) onLocationChanged; // Callback function
const LocationSelector({super.key, required this.onLocationChanged});
@override
LocationSelectorState createState() => LocationSelectorState();
@ -24,38 +27,38 @@ class LocationSelectorState extends State<LocationSelector> {
@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,
),
),
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'),
],
);
),
),
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 {
@ -98,6 +101,17 @@ class LocationSelectorState extends State<LocationSelector> {
_administrativeArea = placeMark.administrativeArea;
errorText = null;
});
// location is found, trigger callback
widget.onLocationChanged(MyLocation(
street: _street,
country: _country,
administrativeArea: _administrativeArea,
locality: _city,
subLocality: _subLocality,
postalCode: _postalCode,
latitude: _latitude,
longitude: _longitude,
));
} else {
setState(() {
// should placeMarks be empty return latitude and longitude anyway

View File

@ -6,6 +6,7 @@ class Constants {
static const String dbCollectionUsers = 'Users';
static const String dbCollectionLanguages = 'languages';
static const String dbCollectionLocations = 'locations';
static const String dbCollectionChatRooms = 'chat_rooms';
static const String dbCollectionMessages = 'messages';

18
lib/helper.dart 100644
View File

@ -0,0 +1,18 @@
/// Convert decimal coordinate to degrees minutes seconds (DMS)
String convertDecimalToDMS(double decimalValue) {
bool isNegative = decimalValue < 0;
double absoluteValue = decimalValue.abs();
int degrees = absoluteValue.toInt();
double minutesDecimal = (absoluteValue - degrees) * 60;
int minutes = minutesDecimal.toInt();
double secondsDecimal = (minutesDecimal - minutes) * 60;
double seconds = double.parse(secondsDecimal.toStringAsFixed(2));
String direction = isNegative
? (decimalValue < 0 ? 'W' : 'S')
: (decimalValue >= 0 ? (degrees != 0 ? 'N' : 'E') : '');
// return formatted string
return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs()}" $direction';
}

View File

@ -1,3 +1,5 @@
import '../helper.dart';
class MyLocation {
final String street;
final String country;
@ -37,6 +39,24 @@ class MyLocation {
};
}
/// Returns: locality, country. In case of an error: latitude, longitude.
String toStringDegree() {
try {
String latResult = convertDecimalToDMS(latitude!);
String longResult = convertDecimalToDMS(longitude!);
return '$latResult, $longResult';
} catch (e) {
// on error return origin values
return '$latitude, $longitude';
}
}
@override
/// Returns: locality, country
String toString() {
return '$locality, $country';
}
@override
int get hashCode => Object.hash(latitude, longitude);

View File

@ -4,11 +4,12 @@ import 'package:cofounderella/components/my_button.dart';
import 'package:cofounderella/constants.dart';
import 'package:cofounderella/models/language.dart';
import 'package:cofounderella/models/language_setting.dart';
import 'package:cofounderella/components/LocationSelector.dart';
import 'package:cofounderella/components/location_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:cofounderella/services/auth/auth_service.dart';
import 'package:cofounderella/models/location.dart';
class UserDataPage extends StatefulWidget {
const UserDataPage({super.key});
@ -20,7 +21,7 @@ class UserDataPage extends StatefulWidget {
enum Gender { none, male, female, divers }
class _UserDataPageState extends State<UserDataPage> {
MyLocation? _selectedLocation;
List<LanguageSetting> languagesList = [];
final List<Language> _selectedLanguages = [];
@ -223,10 +224,23 @@ class _UserDataPageState extends State<UserDataPage> {
'Location',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Padding(
padding: EdgeInsets.all(16.0),
child: LocationSelector(),
Padding(
padding: const EdgeInsets.all(16.0),
child: LocationSelector(
onLocationChanged: (location) {
setState(() {
_selectedLocation = location;
});
},
),
),
// TODO Show and handle selected location
if (_selectedLocation != null) ...[
Text(style: const TextStyle(backgroundColor: Colors.yellow),
'Selected Location: ${_selectedLocation!.toString()}'),
Text(style: const TextStyle(backgroundColor: Colors.yellowAccent),
'Coordinates: ${_selectedLocation!.toStringDegree()}'),
],
const Text(
'Age',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),