Saltar al contenido

Sistema de Rutas en Flutter (Navegaci贸n)

noviembre 14, 2022

Cuando creamos una aplicaci贸n m贸vil con Flutter, en el 99.9% de los casos necesitaremos navegar a diferentes pantallas que tengan diferentes funciones. Opciones tan b谩sicas como el inicio de sesi贸n o registro de nuevos usuarios, deben suceder en pantallas o p谩ginas individuales. En este articulo aprenderemos la nociones b谩sicas para poder movernos entre pantallas.

Tengo un v铆deo en YouTube donde explico esto a bastante detalle, si perefieres ver el v铆deo tambi茅n puedes hacerlo. Hay personas que les es mucho m谩s f谩cil aprender conceptos implementando en tiempo real el c贸digo.

Los sistemas de rutas en Flutter son muy variados, hay (hasta donde yo s茅) 3 formas de implementar rutas y movernos entre pantallas. Es posible que hay m谩s maneras, pero las m谩s usadas son 3, la m谩s vieja y cl谩sica, el sistema de rutas por nombre, y la navegaci贸n 2.0, querida y odiada por igual en las comunidades de programadores.

En este articulo explicaremos el sistema de rutas por nombre, me parece la m谩s sencilla y eficiente de todas. Pero debo mencionar que es un gusto personal, otros programadores prefieren la navegaci贸n 2.0 as铆 que si quieres que hable sobre esa forma de navegaci贸n me lo pueden dejar en los comentarios y con gusto lo har茅.

Sistema de Rutas por Nombre

El sistema de rutas por nombre esta basado en un objeto o map con estructura clave:valor que tiene un texto o string que hace referencia un widget o p谩gina. Este objeto puede tener cantos elementos como sean necesario y debe configurarse en el Material App, es decir al iniciar la aplicaci贸n antes de cargar cualquier pantalla.

El elemento Material App tambi茅n tiene una propiedad que se llama initialRoute que le dice a la aplicaci贸n al es la ruta inicial que se debe cargar al comenzar el proyecto. Dicha initialRoute debe ser una de las claves que se encuentra en el objeto de rutas. El c贸digo de el main quedar铆a algo as铆:

import 'package:flutter/material.dart';
import 'package:sistema_rutas/pages/index.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  MyApp({super.key});

  // rutas disponibles en la app.
  // cada widget es una p谩gina diferente.
  final _routes = {
    '/': (context) => const LoginPage(),
    '/home': (context) => const HomePage(),
    '/otra': (context) => const OtraPage(),
    '/servicios': (context) => const ServiciosPage(),
  };

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      initialRoute: '/',
      // aqu铆 se asigna el objeto a la propiedad de routes
      routes: _routes,
      onGenerateRoute: (settings) {
        // esta opci贸n se ejecuta cuando se llama una ruta que no existe
        return MaterialPageRoute(
          builder: (context) => const Page404(),
        );
      },
    );
  }
}

El objeto _routes contiene referencia a todas las pantallas a las que la aplicaci贸n puede navegar. Por ejemplo 芦/禄 hace referencia a la pantalla de Login. Estoy widgets deben estar creados en otros archivos y contener su propio Scaffold( ). Si tienes alguna duda puedes revisar el repositorio adjunto.

Si te fijas en la l铆nea 22, el initialRoute dice que la ruta inicial es la de Login. Significa que la aplicaci贸n al iniciar, la primera pantalla que cargar谩 ser谩 la de Login. una vez en Login podremos navegar a cualquier otra pantalla.

Navegando a otra pantalla

Para navegar otra pantalla lo podemos hacer usando el objeto Navigator que ya viene en el paquete de Material as铆 que no hace falta importarlo de ning煤n lado. Este objeto tiene un m茅todo llamado push( ), para usar el sistema de rutas por nombre se debe usar el m茅todo pushNamed( ).

El c贸digo de la pantalla de Login quedar铆a algo as铆:

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Login Page'),
      ),
      body: Center(
        child: ElevatedButton(
            onPressed: () {
              // Navegamos a Home
              Navigator.pushNamed(context, "/home");
              
              // si usas pushReplacementNamed la ruta nueva reemplaza la ruta actual.
              // Navigator.pushReplacementNamed(context, '/home');
            },
            child: const Text('Entrar')),
      ),
    );
  }
}

En el ejemplo creamos un bot贸n que al precionarlo nos lleva a la pagina Home. Si te fijas, adem谩s del contexto se env铆o un string que tiene que coincidir con el texto que tiene como clave el objeto _routes en el main.dart.

Con el mismo principio puede navegarse a cualquier ruta que est茅 definida en el objeto _routes. Podemos navegar a la ruta que queramos, haciendo como un sistema de cartas que pone cada pantalla llamada, encima de la pantalla que la llam贸.

Si no queremos que la nueva pantalla se ponga arriba, sino que queremos que sea la 煤nica pantalla disponible, debemos usar pushReplacementNamed( ) lo que destruir谩 la pantalla que invoc贸 la nueva pantalla.

Repositorio en Github: https://github.com/JoseGaldamez/flutter_route_system

Si tienes alguna duda puedes dejarlo en los comentarios y con gusto te estar茅 contestando. Espero que este art铆culo te haya gustado y te haya servido. Hasta la pr贸xima.