¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Flutter
  3. Pop
Extrait - Flutter Desarrolle sus aplicaciones móviles multiplataforma con Dart
Extractos del libro
Flutter Desarrolle sus aplicaciones móviles multiplataforma con Dart Volver a la página de compra del libro

Pop-up y navegación

Introducción

Este capítulo es una oportunidad para descubrir nuevos widgets. En esta parte, se descubrirán varios elementos de presentación. Se relacionan con información adicional que puede resultar conveniente mostrar en la pantalla.

Primero, se describirá el widget SnackBar. Muestra un mensaje al usuario.

Posteriormente, se discutirán otras visualizaciones del tipo «modal». Primero, para mensajes de alerta para el usuario y luego para información simple.

Como continuación, se presentarán hojas de opciones que ofrecen al usuario varias soluciones.

Finalmente, dado que se mencionan las visualizaciones a lo largo de este capítulo, será el momento de centrarse en la navegación de página a página con las rutas.

SnackBar

SnackBar es un mensaje que puede sonar como un «toast», bien conocido en Android. El constructor SnackBar espera varios parámetros. Solo uno es obligatorio, content. Se trata del contenido que es, en la mayoría de los casos, un texto.

Es posible controlar la duración de aparición con la propiedad duration. Como ocurre con muchos widgets, también es posible cambiar su color de fondo con backgroundColor.

Para enriquecerlo, se puede implementar un botón interno. Dependiendo de las necesidades, se le pueden asociar acciones. Esto pasa por el parámetro action alimentado por una instancia de SnackBarAction. Su constructor permite la inserción de una label, un textColor y por supuesto un onPressed.

La aparición del widget snackBar se activa mediante la llamada a:

Scaffold.of(contexto).showSnakBar(nombreDelSnackBarQueDebeAparecer) 

Tenga cuidado, el método of llama al objeto context del Scaffold. Para que esto sea posible, debe estar en un nuevo contexto hijo. Sin un nuevo contexto, se producirá un error.

Este es el proceso de manera esquemática:

images/cap8_pag3.png

Figura 1 - Llamada de Scaffold.of(context)

Para implementar esto, es importante crear una instancia de SnackBar. Por lo tanto, esta se coloca como una variable al comienzo de la clase MyHomePage.

class MyHomePage extends StatelessWidget { 
 MyHomePage({Key key, this.title}) : super(key: key);  
  
 final String title;  
 final SnackBar _snack = SnackBar( 
   content: Text('Esto es una SnackBar'), 
   duration: Duration(seconds: 4), 
   backgroundColor: Colors.red, 
   action: SnackBarAction( 
       label: 'Clic', 
       textColor: Colors.white, 
       onPressed:...

AlertDialog y CupertinoAlertDialog

Los widgets AlertDialog y CupertinoAlertDialog son ventanas emergentes que se utilizan para mostrar un mensaje de alerta al usuario. Permiten llamar su atención.

Responden a la necesidad de obtener una respuesta del usuario o transmitirle algo importante.

Para permitir su visualización, se puede llamar a un método llamado showDialog. Necesariamente espera un parámetro que defina un contexto gracias a BuildContext. Esto devolverá el objeto AlertDialog o CupertinoAlertDialog

Dado que los mensajes pueden ser solo informativos y no siempre requieren una respuesta del usuario, hacer clic fuera de la ventana emergente los cerrará de forma predeterminada. Para evitar este comportamiento, especialmente cuando se espera una acción, el parámetro barrierDismissible puede tomar el valor false. Por lo tanto, el usuario se verá obligado a realizar una de las acciones planificadas y ya no podrá cerrar el cuadro de diálogo presionando fuera.

1. AlertDialog

Los cuadros de diálogo AlertDialog están en estilo Material Design. Tienen un constructor que espera un parámetro llamado content, que a menudo es un texto, pero también puede ser un icono o una imagen.

Para poder interactuar con el usuario, se puede implementar el parámetro action. Espera una lista de widgets.

Por el lado estético, es posible definir un valor de backgroundColor, elegir una elevation o incluso modificar la apariencia del contorno con shape.

Aquí está el código de una aplicación en la que un botón va a activar la apertura de un AlertDialog. Aquí, la apariencia se deja fuera para obtener una representación predeterminada:

import 'package:flutter/cupertino.dart';  
import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget { 
 @override 
 Widget build(BuildContext context) {  
   return MaterialApp(  
     title: 'Flutter Demo', 
     theme:...

SimpleDialog

SimpleDialog y CupertinoDialog, son ventanas emergentes que se utilizan para ofrecer una opción al usuario o para mostrar información.

Se deben considerar con una prioridad menor que AlertDialog.

La implementación se lleva a cabo de manera idéntica a la de AlertDialog. Por tanto, será necesario llamar al método showDialog. Como recordatorio, necesariamente espera un parámetro que defina un contexto gracias a BuildContext. Esto devolverá el AlertDialog o el CupertinoAlertDialog.

Los mensajes pueden ser meramente informativos y no siempre requieren una respuesta del usuario; de forma predeterminada, al hacer clic fuera de la ventana emergente, se cerrará. Para evitar este comportamiento, especialmente cuando se espera una acción, el parámetro barrierDismissible puede tomar el valor false. A partir de ese momento, el usuario se verá obligado a realizar una de las acciones previstas y ya no podrá cerrar la ventana emergente presionando fuera de ella.

1. SimpleDialog

La clase SimpleDialog está en estilo Material Design. Permite la integración de los SimpleDialogActions, que administrarán un evento onPressed y tendrán un hijo (child).

SimpleDialog encaja bien en el contexto de un switch en la medida en que, si se ofrece una opción al usuario, se puede gestionar caso por caso.

Para ilustrar esto, se implementa un ejemplo de una aplicación con un StatefulWidget. De esta manera, será posible gestionar el estado (state).

El objetivo es ofrecer al usuario la posibilidad de elegir un modo de transporte entre coche, avión y barco. Esta elección se hará en el SimpleDialog y se confirmará en la pantalla principal en un texto. Por tanto, es necesario que se recupere y explote el valor elegido.

Se crea una enumeración fuera de la clase _MyHomePageState. Le permite administrar una lista que se podría describir como fija:

enum ListaOpciones{  
 Coche,  
 Avión,  
 Barco 
} 

En la clase _MyHomePageState, se ubica una primera variable. Va a servir para mostrar la opción del usuario:

String _opcion = 'Ninguna opción'; 

Ahora queda construir la parte visual de la aplicación. En el build, se implementa el siguiente código:

@override 
Widget build(BuildContext context)...

Hojas de opción

En el mismo estilo que se vio anteriormente, tenemos lo que se podría traducir al español por hojas de opciones, más explícitamente las BottomSheet y CupertinoActionSheet. Se corresponden con los estilos Material Design e iOS respectivamente. Se pueden utilizar para ocultar contenido demasiado voluminoso en una pantalla, como enlaces de navegación.

1. BottomSheet

Hay varias formas de mostrar una BottomSheet. Este widget rara vez se implementa tal cual. La mayoría de las veces, debe pasar por otros widgets. La documentación recomienda que esta opción recalga en ScaffoldState.showBottomSheet o en showModalBottomSheet. En el siguiente ejemplo, solo se desarrollará el segundo.

Sobre la base del código de la aplicación anterior, donde se parametrizó SimpleDialog para trabajar con una enumeración, se integrará un nuevo botón de activación justo debajo del primero:

RaisedButton( 
 child: Text('Abrir una BottomSheet'), 
 color: Colors.green[700], 
 textColor: Colors.white, 
 onPressed: _queOpcionBottom, 
), 

Esta vez la función que se llama es _queOpcionBottom. En primer lugar, aquí está el código completo de la función, que se detalla a continuación:

Future<void> _queOpcionBottom() async {  
 switch (await showModalBottomSheet<ListaOpcion>( 
     context: context, 
     isDismissible: false, 
     builder: (BuildContext context) {  
       return Center( 
         child: Container( 
           color: Colors.green[200], 
           child: Column( 
             mainAxisAlignment: MainAxisAlignment.spaceAround, 
             children: <Widget>[ 
               Text(  
                 'Seleccione...

Rutas

Ha llegado el momento de centrarse en un punto crucial, las rutas. El objetivo es ver cómo se puede implementar la navegación de pantalla a pantalla.

El widget responsable de esto es la clase Navigator. Funciona colocando pantallas una frente a la otra, en forma de pila. Este efecto de superposición también permite retroceder, ya que esta pila permanece en memoria.

Para ser realmente eficiente, las rutas se pueden definir de antemano en una forma similar a una URL.

1. Navigator.push

Para cambiar a otra pantalla, simplemente use Navigator.push. Se esperan dos parámetros. El primero es el contexto actual. Le permitirá volver a un punto adecuado. El segundo es un objeto MaterialPageRoute. Aquí se creará un nuevo contexto y se indicará a qué página ir.

Para comprender completamente esta implementación, se presenta una primera pantalla con un botón (Figura 11):

@override 
Widget build(BuildContext context) {  
 return Scaffold( 
   appBar: AppBar( 
     title: Text('$title'), 
     backgroundColor: Colors.teal, 
   ), 
   body: Center( 
     child: Column( 
       mainAxisAlignment: MainAxisAlignment.center, 
       children: <Widget>[ 
         Text(  
           "Pantalla n°  1", 
           style: TextStyle(fontWeight: FontWeight.bold, 
fontSize: 40, color: Colors.teal), 
         ), 
         Padding(padding: EdgeInsets.only(bottom: 20)), 
         Text("Pulsar en este botón para pasar a la siguiente pantalla"), 
         Padding(padding: EdgeInsets.only(bottom: 20)), 
         RaisedButton( 
             child: Text('Siguiente'), 
             color:...