feat: slide window logic

This commit is contained in:
imlildud
2026-05-22 18:24:53 -06:00
parent df7b74063b
commit bdde457b45
5 changed files with 260 additions and 178 deletions

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'src/views/rutas.dart'; import 'src/views/rutas.dart';
import 'src/views/main_screen.dart'; // Importar la pantalla principal
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
@@ -13,6 +14,10 @@ class MyApp extends StatelessWidget {
return MaterialApp( return MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Hackaton App', title: 'Hackaton App',
theme: ThemeData(
fontFamily: 'Roboto',
scaffoldBackgroundColor: colorAzul,
),
home: const RegistroView(), home: const RegistroView(),
); );
} }
@@ -54,7 +59,11 @@ class RegistroView extends StatelessWidget {
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)) shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15))
), ),
onPressed: () { onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => const HorariosView())); // ✅ Navegar a la pantalla principal con todas las vistas
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MainScreen()),
);
}, },
child: const Text('Registrar', style: TextStyle(color: Colors.white, fontSize: 18)), child: const Text('Registrar', style: TextStyle(color: Colors.white, fontSize: 18)),
), ),
@@ -64,7 +73,14 @@ class RegistroView extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15), padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)) shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15))
), ),
onPressed: () {}, onPressed: () {
// TODO: Implementar inicio de sesión
// Por ahora también navega a MainScreen
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MainScreen()),
);
},
child: const Text('Iniciar Sesion', style: TextStyle(color: Colors.white, fontSize: 18)), child: const Text('Iniciar Sesion', style: TextStyle(color: Colors.white, fontSize: 18)),
), ),
], ],

View File

@@ -1,61 +1,64 @@
// configuracion.dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'nav_bar.dart';
import 'rutas.dart'; import 'rutas.dart';
import 'domicilios.dart';
import 'horarios.dart';
class ConfiguracionView extends StatelessWidget { class ConfiguracionView extends StatelessWidget {
const ConfiguracionView({super.key}); const ConfiguracionView({super.key});
void _navigateTo(BuildContext context, int index) {
if (index == 2) return; // Ya estamos en Configuración
switch (index) {
case 0:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const DomiciliosView()),
);
break;
case 1:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const HorariosView()),
);
break;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Container(
backgroundColor: Colors.white, color: Colors.white,
appBar: AppBar( child: SafeArea(
backgroundColor: colorAzul,
title: const Text('Configuración',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column( child: Column(
children: [ children: [
GestureDetector( // AppBar personalizado
onTap: () {}, Container(
child: Container( width: double.infinity,
padding: const EdgeInsets.all(15), padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
decoration: BoxDecoration( decoration: const BoxDecoration(
border: Border.all(color: Colors.black, width: 4), color: colorAzul,
borderRadius: BorderRadius.circular(25), borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
), ),
child: const Row( ),
child: const Text(
'Configuración',
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
// Contenido
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [ children: [
Icon(Icons.notifications_active_outlined, size: 60), GestureDetector(
SizedBox(width: 10), onTap: () {},
Text('7 días', child: Container(
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)), padding: const EdgeInsets.all(15),
Spacer(), decoration: BoxDecoration(
Icon(Icons.keyboard_arrow_down, size: 50), border: Border.all(color: Colors.black, width: 4),
borderRadius: BorderRadius.circular(25),
),
child: const Row(
children: [
Icon(Icons.notifications_active_outlined, size: 60),
SizedBox(width: 10),
Text('7 días',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Spacer(),
Icon(Icons.keyboard_arrow_down, size: 50),
],
),
),
),
], ],
), ),
), ),
@@ -63,10 +66,6 @@ class ConfiguracionView extends StatelessWidget {
], ],
), ),
), ),
bottomNavigationBar: CustomNavBar(
currentIndex: 2,
onTap: (index) => _navigateTo(context, index),
),
); );
} }
} }

View File

@@ -1,92 +1,91 @@
// domicilios.dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'nav_bar.dart';
import 'rutas.dart'; import 'rutas.dart';
import 'horarios.dart';
import 'configuracion.dart';
class DomiciliosView extends StatelessWidget { class DomiciliosView extends StatelessWidget {
const DomiciliosView({super.key}); const DomiciliosView({super.key});
void _navigateTo(BuildContext context, int index) {
if (index == 0) return;
switch (index) {
case 1:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const HorariosView()),
);
break;
case 2:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const ConfiguracionView()),
);
break;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Container(
backgroundColor: Colors.white, color: Colors.white, // Fondo blanco para el contenido
appBar: AppBar( child: SafeArea(
backgroundColor: colorAzul,
title: const Text('Domicilios',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column( child: Column(
children: [ children: [
// AppBar personalizado
Container( Container(
padding: const EdgeInsets.all(15), width: double.infinity,
decoration: BoxDecoration( padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
border: Border.all(color: Colors.black, width: 4), decoration: const BoxDecoration(
borderRadius: BorderRadius.circular(25), color: colorAzul,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
), ),
child: Row( child: const Text(
children: [ 'Domicilios',
const Icon(Icons.home_outlined, size: 60), style: TextStyle(
const SizedBox(width: 10), color: Colors.white,
const Column( fontSize: 28,
crossAxisAlignment: CrossAxisAlignment.start, fontWeight: FontWeight.bold,
children: [ ),
Text('Mi Casa', textAlign: TextAlign.center,
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Text('Centro, Ruta 1',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
],
),
const Spacer(),
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_horiz, size: 40),
),
],
), ),
), ),
const SizedBox(height: 20), // Contenido
GestureDetector( Expanded(
onTap: () {}, child: Padding(
child: Container( padding: const EdgeInsets.all(20.0),
width: double.infinity, child: Column(
height: 100, children: [
decoration: BoxDecoration( Container(
color: colorAzul, padding: const EdgeInsets.all(15),
borderRadius: BorderRadius.circular(20), decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 4),
borderRadius: BorderRadius.circular(25),
),
child: Row(
children: [
const Icon(Icons.home_outlined, size: 60),
const SizedBox(width: 10),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Mi Casa',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Text('Centro, Ruta 1',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
],
),
const Spacer(),
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_horiz, size: 40),
),
],
),
),
const SizedBox(height: 20),
GestureDetector(
onTap: () {},
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),
),
),
],
), ),
child: const Icon(Icons.add, color: Colors.white, size: 80),
), ),
), ),
], ],
), ),
), ),
bottomNavigationBar: CustomNavBar(
currentIndex: 0,
onTap: (index) => _navigateTo(context, index),
),
); );
} }
} }

View File

@@ -1,31 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'nav_bar.dart';
import 'rutas.dart'; import 'rutas.dart';
import 'domicilios.dart';
import 'configuracion.dart';
class HorariosView extends StatelessWidget { class HorariosView extends StatelessWidget {
const HorariosView({super.key}); const HorariosView({super.key});
void _navigateTo(BuildContext context, int index) {
if (index == 1) return; // Ya estamos en Horarios
switch (index) {
case 0:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const DomiciliosView()),
);
break;
case 2:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const ConfiguracionView()),
);
break;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<Map<String, String>> rutas = List.generate( final List<Map<String, String>> rutas = List.generate(
@@ -37,43 +15,63 @@ class HorariosView extends StatelessWidget {
}, },
); );
return Scaffold( return Container(
backgroundColor: Colors.white, color: Colors.white,
appBar: AppBar( child: SafeArea(
backgroundColor: colorAzul, child: Column(
title: const Text('Horarios', children: [
style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), // AppBar personalizado
centerTitle: true, Container(
), width: double.infinity,
body: ListView.builder( padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 24), decoration: const BoxDecoration(
itemCount: rutas.length, color: colorAzul,
itemBuilder: (context, index) { borderRadius: BorderRadius.only(
final item = rutas[index]; bottomLeft: Radius.circular(20),
return Padding( bottomRight: Radius.circular(20),
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item['colonia']!,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Text(item['ruta']!,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
],
), ),
Text(item['horario']!, ),
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), child: const Text(
], 'Horarios',
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
), ),
); // Lista de horarios
}, Expanded(
), child: ListView.builder(
bottomNavigationBar: CustomNavBar( padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 24),
currentIndex: 1, itemCount: rutas.length,
onTap: (index) => _navigateTo(context, index), itemBuilder: (context, index) {
final item = rutas[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item['colonia']!,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Text(item['ruta']!,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
],
),
Text(item['horario']!,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
],
),
);
},
),
),
],
),
), ),
); );
} }

View File

@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'rutas.dart';
import 'domicilios.dart';
import 'horarios.dart';
import 'configuracion.dart';
import 'nav_bar.dart';
class MainScreen extends StatefulWidget {
const MainScreen({super.key});
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
late PageController _pageController;
int _currentIndex = 1; // Comenzar en Horarios (Rutas)
@override
void initState() {
super.initState();
_pageController = PageController(initialPage: _currentIndex);
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
void _onPageChanged(int index) {
setState(() {
_currentIndex = index;
});
}
void _onNavBarTap(int index) {
if (_currentIndex != index) {
setState(() {
_currentIndex = index;
});
_pageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: colorAzul, // Mismo color de fondo para evitar flash blanco
body: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
physics: const BouncingScrollPhysics(), // Efecto de rebote al deslizar
children: const [
DomiciliosView(),
HorariosView(),
ConfiguracionView(),
],
),
bottomNavigationBar: CustomNavBar(
currentIndex: _currentIndex,
onTap: _onNavBarTap,
),
);
}
}