feat: gps coords added

This commit is contained in:
imlildud
2026-05-22 23:31:09 -06:00
parent 2d56d6de0d
commit 36c04582f3
2 changed files with 205 additions and 261 deletions

View File

@@ -1,73 +1,87 @@
// src/services/geolocation_service.dart
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart'; import 'dart:async'; // ← IMPORTANTE: Para TimeoutException
class GeolocationService { class GeolocationService {
// Verificar y solicitar permisos de ubicación // Verificar servicios de ubicación
static Future<bool> requestPermission() async { static Future<bool> isLocationServiceEnabled() async {
final status = await Permission.location.request(); return await Geolocator.isLocationServiceEnabled();
return status.isGranted;
} }
// Obtener ubicación actual // Verificar permiso
static Future<LocationPermission> checkPermission() async {
return await Geolocator.checkPermission();
}
// Solicitar permiso
static Future<LocationPermission> requestPermission() async {
return await Geolocator.requestPermission();
}
// Verificar si hay permiso concedido
static Future<bool> hasPermission() async {
LocationPermission permission = await Geolocator.checkPermission();
return permission == LocationPermission.always ||
permission == LocationPermission.whileInUse;
}
// Obtener ubicación actual con timeout
static Future<Position?> getCurrentLocation() async { static Future<Position?> getCurrentLocation() async {
try { try {
// Verificar si los servicios de ubicación están activados // Verificar servicios
bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) { if (!serviceEnabled) {
print('❌ Servicios de ubicación desactivados');
return null; return null;
} }
print('✅ Servicios de ubicación activados');
// Verificar permisos // Verificar permisos
LocationPermission permission = await Geolocator.checkPermission(); LocationPermission permission = await Geolocator.checkPermission();
print('📌 Permiso actual: $permission');
if (permission == LocationPermission.denied) { if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission(); permission = await Geolocator.requestPermission();
print('📌 Permiso solicitado: $permission');
if (permission == LocationPermission.denied) { if (permission == LocationPermission.denied) {
print('❌ Permiso denegado');
return null; return null;
} }
} }
if (permission == LocationPermission.deniedForever) { if (permission == LocationPermission.deniedForever) {
print('❌ Permiso denegado permanentemente');
return null; return null;
} }
// Obtener ubicación // Obtener ubicación
print('📍 Obteniendo ubicación...');
Position position = await Geolocator.getCurrentPosition( Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high, desiredAccuracy: LocationAccuracy.best,
); );
print('✅ Ubicación obtenida: ${position.latitude}, ${position.longitude}');
return position; return position;
} catch (e) { } catch (e) {
print('Error getting location: $e'); print('Error general: $e');
return null; return null;
} }
} }
// Mostrar diálogo de permisos // Obtener ubicación con reintentos (sin timeout que da problemas)
static Future<bool> showPermissionDialog(BuildContext context) async { static Future<Position?> getCurrentLocationWithRetry({int maxRetries = 3}) async {
final result = await showDialog<bool>( for (int i = 0; i < maxRetries; i++) {
context: context, print('🔄 Intento ${i + 1} de $maxRetries');
barrierDismissible: false, final position = await getCurrentLocation();
builder: (context) => AlertDialog( if (position != null) {
title: const Text('Permiso de ubicación'), return position;
content: const Text( }
'Necesitamos acceder a tu ubicación para asignar tu domicilio a la ruta correcta de recolección.', if (i < maxRetries - 1) {
), await Future.delayed(const Duration(seconds: 2));
actions: [ }
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('Cancelar'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('Aceptar', style: TextStyle(color: colorAzul)),
),
],
),
);
if (result == true) {
return await requestPermission();
} }
return false; print('❌ No se pudo obtener ubicación después de $maxRetries intentos');
return null;
} }
} }

View File

@@ -1,9 +1,12 @@
// domicilios.dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
import 'rutas.dart'; import 'rutas.dart';
import '../models/domicilio_model.dart'; import '../models/domicilio_model.dart';
import '../services/geolocation_service.dart'; import '../services/geolocation_service.dart';
import 'nav_bar.dart';
import 'main_screen.dart';
class DomiciliosView extends StatefulWidget { class DomiciliosView extends StatefulWidget {
const DomiciliosView({super.key}); const DomiciliosView({super.key});
@@ -15,12 +18,8 @@ class DomiciliosView extends StatefulWidget {
class _DomiciliosViewState extends State<DomiciliosView> { class _DomiciliosViewState extends State<DomiciliosView> {
List<Domicilio> domicilios = []; List<Domicilio> domicilios = [];
bool _isLoading = true; bool _isLoading = true;
// Ubicación actual
Position? _currentPosition;
bool _isLoadingLocation = false; bool _isLoadingLocation = false;
// Controladores para el formulario
final TextEditingController nombreController = TextEditingController(); final TextEditingController nombreController = TextEditingController();
final TextEditingController coloniaController = TextEditingController(); final TextEditingController coloniaController = TextEditingController();
final TextEditingController calleController = TextEditingController(); final TextEditingController calleController = TextEditingController();
@@ -69,51 +68,126 @@ class _DomiciliosViewState extends State<DomiciliosView> {
} }
} }
// Obtener ubicación actual y mostrar diálogo Future<bool> _showLocationPermissionDialog() async {
if (await GeolocationService.hasPermission()) {
return true;
}
final result = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: const Text('Permiso de ubicación'),
content: const Text(
'Necesitamos acceder a tu ubicación para asignar tu domicilio a la ruta correcta.',
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('Cancelar'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('Aceptar', style: TextStyle(color: colorAzul)),
),
],
),
);
if (result == true) {
LocationPermission newPermission = await GeolocationService.requestPermission();
return newPermission == LocationPermission.always ||
newPermission == LocationPermission.whileInUse;
}
return false;
}
// ⬇️⬇️⬇️ ESTE ES EL MÉTODO QUE DEBES TENER ⬇️⬇️⬇️
Future<void> _obtenerUbicacionYAgregar() async { Future<void> _obtenerUbicacionYAgregar() async {
print('🔵 Iniciando obtención de ubicación');
setState(() { setState(() {
_isLoadingLocation = true; _isLoadingLocation = true;
}); });
// Solicitar permisos // Verificar GPS
final hasPermission = await GeolocationService.showPermissionDialog(context); final serviceEnabled = await GeolocationService.isLocationServiceEnabled();
print('📡 GPS activado: $serviceEnabled');
if (!serviceEnabled) {
setState(() {
_isLoadingLocation = false;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Activa el GPS para agregar un domicilio'),
backgroundColor: Colors.orange,
duration: Duration(seconds: 3),
),
);
return;
}
// Verificar permisos
final hasPermission = await _showLocationPermissionDialog();
print('🔐 Permiso concedido: $hasPermission');
if (!hasPermission) { if (!hasPermission) {
setState(() { setState(() {
_isLoadingLocation = false; _isLoadingLocation = false;
}); });
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Necesitamos tu ubicación para agregar un domicilio'), content: Text('Necesitamos tu ubicación para continuar'),
backgroundColor: Colors.orange, backgroundColor: Colors.orange,
duration: Duration(seconds: 3),
), ),
); );
return; return;
} }
// Obtener ubicación // Mostrar mensaje de "obteniendo ubicación"
final position = await GeolocationService.getCurrentLocation(); ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Row(
children: [
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
),
SizedBox(width: 10),
Text('Obteniendo tu ubicación...'),
],
),
backgroundColor: colorAzul,
duration: Duration(seconds: 5),
),
);
// Obtener ubicación con reintentos
final position = await GeolocationService.getCurrentLocationWithRetry(maxRetries: 3);
setState(() { setState(() {
_isLoadingLocation = false; _isLoadingLocation = false;
_currentPosition = position;
}); });
if (position == null) { if (position == null) {
print('❌ No se pudo obtener ubicación después de reintentos');
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('No se pudo obtener tu ubicación. Activa el GPS.'), content: Text('No se pudo obtener tu ubicación. Revisa tu GPS.'),
backgroundColor: Colors.red, backgroundColor: Colors.red,
duration: Duration(seconds: 4),
), ),
); );
return; return;
} }
// Mostrar diálogo con la ubicación obtenida print('✅ Ubicación obtenida exitosamente: ${position.latitude}, ${position.longitude}');
_mostrarDialogoAgregarConUbicacion(position); _mostrarDialogoAgregarConUbicacion(position);
} }
void _mostrarDialogoAgregarConUbicacion(Position position) { void _mostrarDialogoAgregarConUbicacion(Position position) {
// Limpiar controladores
nombreController.clear(); nombreController.clear();
coloniaController.clear(); coloniaController.clear();
calleController.clear(); calleController.clear();
@@ -130,23 +204,16 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// Título
const Text( const Text(
'Añadir domicilio', 'Añadir domicilio',
style: TextStyle( style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: colorAzul),
fontSize: 24,
fontWeight: FontWeight.bold,
color: colorAzul,
),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
// Mostrar ubicación obtenida
Container( Container(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.green.withOpacity(0.1), color: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.green.withOpacity(0.3)),
), ),
child: Row( child: Row(
children: [ children: [
@@ -156,22 +223,10 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text('📍 Ubicación obtenida',
'📍 Ubicación obtenida', style: TextStyle(fontSize: 12, color: Colors.green[700])),
style: TextStyle( Text('Lat: ${position.latitude.toStringAsFixed(6)}'),
fontSize: 12, Text('Lng: ${position.longitude.toStringAsFixed(6)}'),
color: Colors.green[700],
fontWeight: FontWeight.bold,
),
),
Text(
'Lat: ${position.latitude.toStringAsFixed(6)}',
style: const TextStyle(fontSize: 11),
),
Text(
'Lng: ${position.longitude.toStringAsFixed(6)}',
style: const TextStyle(fontSize: 11),
),
], ],
), ),
), ),
@@ -179,36 +234,14 @@ class _DomiciliosViewState extends State<DomiciliosView> {
), ),
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
// Campo: Nombre del domicilio _buildCampoTexto(controller: nombreController, hint: 'Nombre del domicilio', icon: Icons.home_outlined),
_buildCampoTexto(
controller: nombreController,
hint: 'Nombre del domicilio',
icon: Icons.home_outlined,
),
const SizedBox(height: 15), const SizedBox(height: 15),
// Campo: Colonia _buildCampoTexto(controller: coloniaController, hint: 'Colonia', icon: Icons.location_city_outlined),
_buildCampoTexto(
controller: coloniaController,
hint: 'Colonia',
icon: Icons.location_city_outlined,
),
const SizedBox(height: 15), const SizedBox(height: 15),
// Campo: Calle _buildCampoTexto(controller: calleController, hint: 'Calle', icon: Icons.streetview),
_buildCampoTexto(
controller: calleController,
hint: 'Calle',
icon: Icons.streetview,
),
const SizedBox(height: 15), const SizedBox(height: 15),
// Campo: Número _buildCampoTexto(controller: numeroController, hint: 'Número', icon: Icons.numbers, keyboardType: TextInputType.number),
_buildCampoTexto(
controller: numeroController,
hint: 'Número',
icon: Icons.numbers,
keyboardType: TextInputType.number,
),
const SizedBox(height: 25), const SizedBox(height: 25),
// Botones
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
@@ -216,18 +249,10 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: OutlinedButton( child: OutlinedButton(
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
side: BorderSide(color: colorAzul, width: 2), side: BorderSide(color: colorAzul, width: 2),
padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
onPressed: () {
Navigator.pop(context);
},
child: const Text(
'Cancelar',
style: TextStyle(fontSize: 16, color: colorAzul),
), ),
onPressed: () => Navigator.pop(context),
child: const Text('Cancelar', style: TextStyle(color: colorAzul)),
), ),
), ),
const SizedBox(width: 15), const SizedBox(width: 15),
@@ -235,21 +260,10 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: colorAzul, backgroundColor: colorAzul,
padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
onPressed: () {
_agregarDomicilio(
latitud: position.latitude,
longitud: position.longitude,
);
},
child: const Text(
'Agregar',
style: TextStyle(fontSize: 16, color: Colors.white),
), ),
onPressed: () => _agregarDomicilio(latitud: position.latitude, longitud: position.longitude),
child: const Text('Agregar', style: TextStyle(color: Colors.white)),
), ),
), ),
], ],
@@ -274,10 +288,7 @@ class _DomiciliosViewState extends State<DomiciliosView> {
decoration: InputDecoration( decoration: InputDecoration(
hintText: hint, hintText: hint,
prefixIcon: Icon(icon, color: colorAzul), prefixIcon: Icon(icon, color: colorAzul),
border: OutlineInputBorder( border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(color: colorAzul),
),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
borderSide: BorderSide(color: colorAzul.withOpacity(0.5)), borderSide: BorderSide(color: colorAzul.withOpacity(0.5)),
@@ -290,28 +301,23 @@ class _DomiciliosViewState extends State<DomiciliosView> {
); );
} }
void _agregarDomicilio({required double latitud, required double longitud}) { void _agregarDomicilio({required double latitud, required double longitud}) async {
// Validar campos if (nombreController.text.trim().isEmpty ||
if (nombreController.text.isEmpty || coloniaController.text.trim().isEmpty ||
coloniaController.text.isEmpty || calleController.text.trim().isEmpty ||
calleController.text.isEmpty || numeroController.text.trim().isEmpty) {
numeroController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(content: Text('Llena todos los campos'), backgroundColor: Colors.red),
content: Text('Por favor, llena todos los campos'),
backgroundColor: Colors.red,
),
); );
return; return;
} }
// Crear nuevo domicilio con lat/lng
final nuevoDomicilio = Domicilio( final nuevoDomicilio = Domicilio(
id: DateTime.now().millisecondsSinceEpoch.toString(), id: DateTime.now().millisecondsSinceEpoch.toString(),
nombre: nombreController.text, nombre: nombreController.text.trim(),
colonia: coloniaController.text, colonia: coloniaController.text.trim(),
calle: calleController.text, calle: calleController.text.trim(),
numero: numeroController.text, numero: numeroController.text.trim(),
latitud: latitud, latitud: latitud,
longitud: longitud, longitud: longitud,
); );
@@ -320,58 +326,49 @@ class _DomiciliosViewState extends State<DomiciliosView> {
domicilios.add(nuevoDomicilio); domicilios.add(nuevoDomicilio);
}); });
_guardarDomicilios(); await _guardarDomicilios();
Navigator.pop(context); Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(content: Text('Domicilio agregado'), backgroundColor: colorAzul, duration: const Duration(seconds: 2)),
content: Text('Domicilio "${nombreController.text}" agregado'),
backgroundColor: colorAzul,
duration: const Duration(seconds: 2),
),
); );
} }
void _eliminarDomicilio(int index) async { void _eliminarDomicilio(int index) async {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (context) => AlertDialog(
return AlertDialog( title: const Text('Eliminar domicilio'),
title: const Text('Eliminar domicilio'), content: Text('¿Eliminar "${domicilios[index].nombre}"?'),
content: Text('¿Deseas eliminar "${domicilios[index].nombre}"?'), actions: [
actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text('Cancelar')),
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () async {
child: const Text('Cancelar'), setState(() => domicilios.removeAt(index));
), await _guardarDomicilios();
TextButton( Navigator.pop(context);
onPressed: () async { },
setState(() { child: const Text('Eliminar', style: TextStyle(color: Colors.red)),
domicilios.removeAt(index); ),
}); ],
await _guardarDomicilios(); ),
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Domicilio eliminado'),
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
),
);
},
child: const Text('Eliminar', style: TextStyle(color: Colors.red)),
),
],
);
},
); );
} }
void _navegarA(int index) {
if (index == 1) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MainScreen()),
);
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Scaffold(
color: Colors.white, backgroundColor: Colors.white,
child: SafeArea( body: SafeArea(
child: Column( child: Column(
children: [ children: [
Container( Container(
@@ -379,20 +376,9 @@ class _DomiciliosViewState extends State<DomiciliosView> {
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: colorAzul, color: colorAzul,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
child: const Text(
'Domicilios',
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
), ),
child: const Text('Domicilios', style: TextStyle(color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
), ),
Expanded( Expanded(
child: _isLoading child: _isLoading
@@ -402,27 +388,11 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(Icons.home_outlined, size: 100, color: Colors.grey.withOpacity(0.5)),
Icons.home_outlined,
size: 100,
color: Colors.grey.withOpacity(0.5),
),
const SizedBox(height: 20), const SizedBox(height: 20),
Text( Text('No hay domicilios', style: TextStyle(fontSize: 18, color: Colors.grey.withOpacity(0.7))),
'No hay domicilios agregados',
style: TextStyle(
fontSize: 18,
color: Colors.grey.withOpacity(0.7),
),
),
const SizedBox(height: 10), const SizedBox(height: 10),
Text( Text('Toca el botón + para agregar', style: TextStyle(fontSize: 14, color: Colors.grey.withOpacity(0.5))),
'Toca el botón + para agregar',
style: TextStyle(
fontSize: 14,
color: Colors.grey.withOpacity(0.5),
),
),
], ],
), ),
) )
@@ -430,7 +400,7 @@ class _DomiciliosViewState extends State<DomiciliosView> {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
itemCount: domicilios.length, itemCount: domicilios.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final domicilio = domicilios[index]; final d = domicilios[index];
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: 20), padding: const EdgeInsets.only(bottom: 20),
child: Container( child: Container(
@@ -447,36 +417,13 @@ class _DomiciliosViewState extends State<DomiciliosView> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(d.nombre, style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
domicilio.nombre, Text(d.direccionCompleta, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
style: const TextStyle( Text('📍 ${d.latitud.toStringAsFixed(4)}, ${d.longitud.toStringAsFixed(4)}', style: TextStyle(fontSize: 12, color: Colors.grey[600])),
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
Text(
domicilio.direccionCompleta,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
// Mostrar lat/lng (para debug)
Text(
'📍 ${domicilio.latitud.toStringAsFixed(4)}, ${domicilio.longitud.toStringAsFixed(4)}',
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
),
),
], ],
), ),
), ),
IconButton( IconButton(onPressed: () => _eliminarDomicilio(index), icon: const Icon(Icons.delete_outline, size: 40), color: Colors.red),
onPressed: () => _eliminarDomicilio(index),
icon: const Icon(Icons.delete_outline, size: 40),
color: Colors.red,
),
], ],
), ),
), ),
@@ -487,33 +434,16 @@ class _DomiciliosViewState extends State<DomiciliosView> {
Padding( Padding(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: _isLoadingLocation child: _isLoadingLocation
? Container( ? Container(width: double.infinity, height: 100, decoration: BoxDecoration(color: colorAzul, borderRadius: BorderRadius.circular(20)), child: const Center(child: CircularProgressIndicator(color: Colors.white)))
width: double.infinity,
height: 100,
decoration: BoxDecoration(
color: colorAzul,
borderRadius: BorderRadius.circular(20),
),
child: const Center(
child: CircularProgressIndicator(color: Colors.white),
),
)
: GestureDetector( : GestureDetector(
onTap: _obtenerUbicacionYAgregar, onTap: _obtenerUbicacionYAgregar,
child: Container( child: Container(width: double.infinity, height: 100, decoration: BoxDecoration(color: colorAzul, borderRadius: BorderRadius.circular(20)), child: const Icon(Icons.add, color: Colors.white, size: 80)),
width: double.infinity,
height: 100,
decoration: BoxDecoration(
color: colorAzul,
borderRadius: BorderRadius.circular(20),
),
child: const Icon(Icons.add, color: Colors.white, size: 80),
),
), ),
), ),
], ],
), ),
), ),
bottomNavigationBar: CustomNavBar(currentIndex: 0, onTap: _navegarA),
); );
} }
} }