Flutter V: Material Design II — [Flutter 1.0]

Fabio Santana
7 min readOct 3, 2016

--

Flutter nos ofrece muchos más widgets para crear interfaces de usuario que sigan los principios de Material Design que los que hemos visto hasta ahora. Nuestro siguiente paso en esta serie de artículos sobre Flutter es añadir a nuestra app una vista del detalle de cada contacto. Para esto conoceremos como: manejar el tap del usuario en una lista, navegar entre las pantallas y conocer más sobre determinados widgets.

Actualizado a Flutter 1.0 — Diciembre 2018

Índice

Recuerda que dispones de todo el código que vamos viendo en este repo.

Objetivo

Nuestro objetivo para este artículo es crear algo parecido a esto:

Detalle de un contacto

Una vista donde la imagen del contacto pueda contraerse al hacer scroll en sus datos personales.

Datos del contacto

En el anterior tutorial sobre Flutter utilizamos el servicio de RandomUser para mostrar en una lista el nombre y el email de los contactos. Para esta nueva vista necesitaremos más datos y no solo esos dos por lo que el primer paso será obtenerlos del Json que nos devuelve RandomUser.

Estos cambios los hacemos en el archivo contact_data.dart y como puedes ver hemos obtenido directamente del mapa: el género y la url de la imagen del contacto.

Para la fecha utilizamos el DateTime.parse primero para parsear la fecha que nos llega como una String y luego le damos formato con DataFormat. Sí desde RandomUser nos envían este formato 1983–07–14 07:29:45 nosotros lo estaremos convirtiendo a Julio 14, 1983.

Para poder hacer uso esas clases debemos añadir la siguiente dependencia en nuestro pubspec.yaml y hacer un flutter packages get.

intl: ^0.15.7

Luego creamos dos nuevas clases para que contenga información más compleja como son la localización y el teléfono. En el caso del teléfono lo definimos como una lista para poder mostrar luego más de uno en la vista del detalle del contacto.

Detalle del Contacto

Dentro de la carpeta /lib/module/contacts creamos un nuevo archivo llamado contact_detail_view.dart que contendrá obviamente la vista de detalle del contacto.

Para hacer esto vamos a crearnos tres tipos de widget:

  • ContactPage La página que muestra todo el detalle del contacto.
  • FlexibleAppBar Este será nuestro app bar personalizado, una app bar que tenga una imagen y que se pueda contraer.
  • _ContactCategory Para que podamos separar cada dato personal crearemos esta clase que contendrá uno o varios _ContactCategoryItem.
  • _ContactCategoryItem Este widget lo usaremos para mostrar un dato en concreto.

En esta imagen puedes ver cada elemento de la vista que vamos a crear.

Flexible App Bar

La imagen del contacto la mostraremos en un app bar que se pueda contraer. Como será un widget que podamos reutilizar en más pantallas lo pondremos en otro archivo y no en contact_detail_view.dart. En la carpeta lib creamos una nueva carpeta llamada widget que contendrán nuestros widgets personalizados y en esta un nuevo archivo app_bar.dart.

Nuestro FlexibleAppBar extenderá del SliverAppBar del SDK de Flutter y en el constructor lo llamamos con el super. Al super le pasamos el tamaño que vamos a dar a nuestro FlexibleAppBar además de un flexibleSpace. El SliverAppBar de Flutter ya viene preparado con un campo llamado flexibleSpace para poder añadir un widget que se pueda contraer y expandir.

A este flexibleSpace le pasamos un nuevo FlexibleSpaceBar que tiene un título el cual ya nos lo posiciona justo donde las especificaciones de Material Design especifica. En cuanto al background creamos uno nuestro propio compuesto por una imagen y un degradado.

Para construir el widget del background utilizamos el widget Stack. El widget Stack es un widget que superpone uno encima de otro una lista de widgets, en Android su equivalente es un FrameLayout.

Lo que queremos hacer es poner una imagen y encima de esta un degradado a la altura de donde ira el título para que pueda verse este mejor. En la siguiente imagen podrás ver mejor lo que queremos hacer.

Flexible App Bar Background

Para mostrar la imagen usamos el widget Image y para el degradado usamos el widget DecoratedBox.

Para poder pintar en el widget usamos un decoration, en este caso del tipo BoxDecoration. El BoxDecoration nos permite pasarle un gradiente, este gradiente nos interesa que sea un LinearGradient para conseguir el efecto que hemos comentado.

Para construir un LinearGradient debemos pasar el comienzo y el final, además de la lista de colores a aplicar. Tanto el atributo begin como end aceptan un FractionalOffset, el FractionalOffset tiene como parámetros los offsets en x e y. Sí ponemos FractionalOffset(0.0, 0.0) estamos especificando la esquina superior izquierda.

Nuestro título irá en la parte inferior del AppBar por lo que necesitamos aplicar el gradiente en esta parte. La clave está en el offset de (y) dado que al ser lineal y quererlo hacer en vertical la única condición que debe seguir el offset de (x) es que en ambos casos sea el mismo.

Dicho esto al pasar un 0.6 en el begin y un 1.0 en el end estamos diciendo que queremos que el gradiente empiece al 60% de la altura desde la parte superior y acabe en el 100% de la misma. En esta imagen lo podremos ver mejor.

LinearGradient

Contact Category Item

Con el _ContactCategoryItem queremos ir mostrando cada dato personal del contacto dentro de una categoría.

Cada ítem tendrá un icono y unas líneas que describan el valor de un dato personal en concreto.

Construimos un Row dentro de un padding, el widget Row nos permite mostrar horizontalmente varios widget como en Android pudiera ser un LinearLayout con un orientation horizontal. Dentro del Row queremos una parte para los datos y otra a la derecha para el icono.

_ContactCategoryItem

Para el dato usamos el widget Flexible porque no sabemos cuan grande será el dato a mostrar. A su vez al Flexible widget como child le pasamos un Column para poder alinear verticalmente cada línea en que se componga los datos para este ítem. Pero antes de todo esto hemos convertido cada línea en una lista de Text con un map.

Contact Category

Los ítems que creamos con el widget _ContactCategoryItem los agrupamos en categorías que creamos con el widget _ContactCategory.

Al constructor le pasamos una lista de ContactCategoryItem y el icono para la categoría. Construimos el widget a partir de un Container, al Container para mostrar una separación entre categorías le ponemos un decoration.

Queremos poner un icono para cada categoría a la izquierda y a la derecha de él los items de esa categoría. Para esto creamos un Row con un container para el icono y un Flexible widget con un Column para mostrar la lista de items en vertical de esta categoría.

Category

Contact Page

Por último debemos crear la página que contendrá el FlexibleAppBar y las categorías que a su vez contendrán los ítems.

Como widget usaremos un Theme para poder poner uno propio a la vista, en este caso diferenciamos el tipo de tema a aplicar según el género del contacto.

primarySwatch: _contact.gender == ‘male’ ? Colors.teal : Colors.pink

Como child usamos un Scaffold de la manera que explicamos en anteriores tutoriales sobre Flutter. En esta pantalla queremos poder hacer scroll por eso debemos añadir como child del Scaffold un CustomScrollView. Este CustomScrollView tiene un atributo llamado slivers que nos va a permitir hacer scroll sobre ellos. Al CustomScrollView le añadimos dos sliver nuestro FlexibleAppBar creado antes y una SliverList a la cual le pasamos una lista de categorías.

En el caso de los teléfonos creamos un nuevo método para crear su categoría _buildPhoneCategory y para el resto creamos _buildCategory.

Navegación

Como último paso de este tutorial debemos hacer que cada vez que el usuario haga tap en un contacto se abra la vista de detalle del mismo. El cambio en la clase _ContactListState es el siguiente.

Cuando creamos cada _ContactListItem agregamos un lambda al atributo onTap para que cuando el usuario haga tap en ese ítem se llame al método _showContact.

En _showContact usamos la clase Navigator que nos ayuda a navegar entre páginas. Con un push insertamos una nueva página encima de la actual y con un pop la retiramos. Debemos crear un MaterialPageRoute para hacer la navegación añadiendo al settings la ruta y al builder la página destino, en este caso el detalle del contacto ConctactPage.

Resultado

Al ejecutar en este punto la aplicación este es el resultado que obtendremos.

Conclusión

En este nuevo artículo sobre Flutter seguimos viendo como de sencillo es crear las interfaces mediante widgets y que respeten las especificaciones de Material Design. Además hemos visto como ponemos navegar y pasar datos entre páginas.

En el próximo articulo veremos como añadir un menú lateral a nuestra app.

Este artículo corresponde al step4 de nuestro repositorio en GitHub.

--

--