web_flutter_tank_appwrite_app/lib/pages/examples/geolocation_example.dart
2025-10-22 08:43:20 +02:00

266 lines
10 KiB
Dart

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,
),
),
],
),
);
}
}