import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../controllers/geolocation_controller.dart'; /// GetX View für Geolocation Funktionalität class GeolocationExample extends StatelessWidget { const GeolocationExample({super.key}); @override Widget build(BuildContext context) { // Controller wird automatisch erstellt und verwaltet final GeolocationController controller = Get.put(GeolocationController()); return Scaffold( appBar: AppBar( title: const Text('Geolocation Beispiel'), backgroundColor: Theme.of(context).colorScheme.inversePrimary, actions: [ // Reset Button in der AppBar IconButton( onPressed: controller.reset, icon: const Icon(Icons.refresh), tooltip: 'Zurücksetzen', ), ], ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Status Card Obx(() => Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Text( 'Status:', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const Spacer(), if (controller.isLoading) const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ), if (controller.isTracking) Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(12), ), child: const Text( 'TRACKING', style: TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 8), Text(controller.statusText), ], ), ), )), const SizedBox(height: 16), // Position Details Card Obx(() => controller.hasPosition ? Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Aktuelle Position:', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), _buildPositionDetail( 'Breitengrad:', controller.currentPosition!.latitude.toStringAsFixed(6), Icons.location_on, ), _buildPositionDetail( 'Längengrad:', controller.currentPosition!.longitude.toStringAsFixed(6), Icons.location_on, ), if (controller.ptvModel != null && controller.ptvModel!.locations != null && controller.ptvModel!.locations!.isNotEmpty) _buildPositionDetail( 'Adresse:', '${controller.ptvModel!.locations!.first.formattedAddress}', Icons.add_home_rounded, ), _buildPositionDetail( 'Genauigkeit:', '${controller.currentPosition!.accuracy.toStringAsFixed(1)} m', Icons.gps_fixed, ), _buildPositionDetail( 'Höhe:', '${controller.currentPosition!.altitude.toStringAsFixed(1)} m', Icons.height, ), _buildPositionDetail( 'Geschwindigkeit:', '${controller.currentSpeedKmh.toStringAsFixed(1)} km/h', Icons.speed, ), _buildPositionDetail( 'Zeit:', controller.currentPosition!.timestamp.toString(), Icons.access_time, ), ], ), ), ) : const SizedBox.shrink()), const SizedBox(height: 16), // Action Buttons Column( children: [ // Aktuelle Position Button Obx(() => SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: controller.isLoading ? null : controller.getCurrentPosition, icon: controller.isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.my_location), label: const Text('Aktuelle Position ermitteln'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), ), ), )), const SizedBox(height: 12), // Tracking Toggle Button Obx(() => SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: controller.isLoading ? null : controller.toggleTracking, icon: Icon(controller.isTracking ? Icons.stop : Icons.play_arrow), label: Text(controller.isTracking ? 'Tracking stoppen' : 'Tracking starten'), style: ElevatedButton.styleFrom( backgroundColor: controller.isTracking ? Colors.red : Colors.green, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 12), ), ), )), const SizedBox(height: 12), // Permissions Button Obx(() => SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: controller.isLoading ? null : controller.checkPermissions, icon: const Icon(Icons.security), label: const Text('Berechtigungen prüfen'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), ), ), )), const SizedBox(height: 12), // Settings Buttons Row Row( children: [ Expanded( child: ElevatedButton.icon( onPressed: controller.openLocationSettings, icon: const Icon(Icons.location_city), label: const Text('Location'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), ), ), ), const SizedBox(width: 8), Expanded( child: ElevatedButton.icon( onPressed: controller.openAppSettings, icon: const Icon(Icons.settings), label: const Text('App'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), ), ), ), ], ), ], ), // Bottom Spacing const SizedBox(height: 24), ], ), ), ), ); } /// Hilfsmethode zum Erstellen von Position Details Widget _buildPositionDetail(String label, String value, IconData icon) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Row( children: [ Icon(icon, size: 16, color: Colors.grey[600]), const SizedBox(width: 8), Text( label, style: const TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(width: 8), Expanded( child: Text( value, style: const TextStyle(fontFamily: 'monospace'), overflow: TextOverflow.ellipsis, ), ), ], ), ); } }