Flutter III: Listas e ítems — [Flutter 1.0]

Fabio Santana
6 min readSep 6, 2016

--

En este nuevo post sobre Flutter nos centraremos en como construir una lista de ítems. Crearemos una pantalla de contactos que muestre una lista de widgets que representen cada contacto y que nos permita hacer scroll sobre ella.

Actualizado a Flutter 1.0 — Diciembre 2018

Índice

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

Planteamiento

Antes de empezar a ver el código vamos a definir que queremos hacer y del modo que lo vamos hacer. Como hemos dicho queremos una pantalla que muestre una lista de contactos. Esta pantalla la dividiremos en tres tipos de Widgets, en la siguiente imagen puedes observar cada uno de estos tipos de Widgets.

  • ContactListItem Widget que muestra la información de cada contacto.
  • ContactList Para crear la lista de contactos crearemos este widget que contendrá una lista de widgets del tipo ContactListItem.
  • ContactsPage Este widget contendrá toda la página y está formado por el widget AppBar y por la lista de widgets (ContactList).

Main y Material App

Al igual que en los tutoriales anteriores debemos crear un método main y dentro llamar al método runApp con un widget del tipo MaterialApp.

En el atributo home le pasaremos una instancia del widget ContactsPage.

Datos de contactos

Para simplificar el ejemplo vamos a obtener los datos de los contactos desde el mismo código y se lo pasaremos al constructor del ContactsList. En el siguiente tutorial veremos como hacerlo desde un servicio.

Lo primero que vamos hacer es crearnos un nuevo archivo llamado contact_data.dart a la altura de nuestro main.dart en la carpeta lib.

Lo siguiente es definir una clase para especificar los datos de un contacto, como pueden ser: el nombre, email, teléfono, dirección… En este archivo creamos la siguiente clase.

Es una simple clase donde definimos dos datos de un usuario. Al pasarle los parámetros al constructor como opcionales, con los {}, nos permite luego pasar ambos por nombre. Además ponemos el constructor como const para poder crear instancias constantes en tiempo de compilación.

El siguiente paso es crear una lista de contactos de ejemplo, aquí tenemos un ejemplo con solo dos contactos.

La primera parte de la sentencia, el const kContacts, define una variable contante la cual no se puede volver asignar. La segunda parte de la misma sentencia, el const <Contact> [], define una lista inmutable. Y dentro de la lista creamos instancias de la clase Contact para cada contacto. A la hora de crear el contacto usamos const Contact y no new Contact para que sea constante en tiempo de compilación. Como podemos ver al poner como opcionales los atributos de la clase Contact podemos asignarlos por nombre.

ContactListItem

Vamos a empezar a ver los tres widgets desde el más interno al más externos. En este caso el mas interno en el ContactListItem.

Como vimos en el anterior post, Flutter nos proporciona dos tipo de widgets para la mayoría de widgets que queramos crear. Estos eran StatelessWidget y StatefulWidget, para nuestro ContactListItem utilizaremos el StatelessWidget. El motivo es que nuestro widget solo mostrará información que no cambiará, siempre serán los mismo datos para un contacto. Entonces nuestro widget quedará de la siguiente manera.

Al igual que con los datos de los contactos nos creamos un archivo para los widgets de los contactos, lo llamaremos contact_view.dart y lo pondremos en la carpeta lib junto a los otros dos archivos main.dart y contact_data.dart.

Al constructor le pasamos un contacto y en el método build devolvemos una instancia del widget ListTile. El widget ListTile es un widget que nos proporciona Flutter y que sigue la especificación de material design, podríamos devolver cualquier otro widget como pudiera ser un Text o un Image pero ListTile como veremos nos ahorra mucho trabajo.

Entre otros los atributos del ListTile son:

  • leading Un widget que se pone antes del título, normalmente suele ser un circulo con un letra, llamado en Flutter CircleAvatar, o por ejemplo la imagen de un usuario.
  • title Widget que define la primera línea de texto del ítem
  • subtitle Widget que define la segunda línea de texto, su posición es debajo del title.

Aquí tenemos un ejemplo de la estructura de un ListTile.

Contact List Tile

En este ejemplo, construimos un ListTile con un CircleAvatar como leading con un Text como hijo con la inicial del nombre del contacto. Como title pasamos un widget Text con el fullName del contacto y como subtitle su email.

Una manera más compacta para definer widget ContactListItem es haciendo que extienda de un ListTile. En el build estamos devolviendo un ListTile por lo que podemos hacer que el mismo ContactListItem lo sea y en el constructor llamar al constructor del ListTile quedando el código de la siguiente manera.

ContactList

Ya tenemos los items de la lista ahora vamos con la lista en sí. Al igual que con el ContactListItem vamos a usar un widget que respecta Material Design, en este caso es ListView. ListView es un widget que nos proporciona la manera de hacer una lista en la que se pueda hacer scroll.

El código de ContactList es el siguiente:

Al igual que el ContactListItem el ContactList es un StatelessWidget. En este caso vemos como hemos declarado final la lista de contactos que nos pasan por el constructor.

Para hacer uso de la clase Contact debemos importar el archivo contact_data.dart creado antes. Lo hacemos de la siguiente manera al inicio del archivo.

import ‘contact_data.dart’;

En el método build devolvemos una instancia del widget ListView, alguno de los atributos que le pasamos son: el padding vertical de la lista y el atributo children que contendrá los ítems de la lista, ítems del tipo ContactListItem.

Para crear la lista de ítems nos hemos creado una nueva función _buildContacList. En ella iteramos la lista de datos de contactos con un map, en el map convertimos cada contacto en un ContactListItem y por último creamos la lista con todos esos ContactListItem con el método toList.

En caso que no hayas visto nunca programación funcional el equivalente a esa función es esta otra.

List<_ContactListItem> _buildContactList() {  var items = new List<_ContactListItem>();  for (var contact in _contacts){
items.add(new _ContactListItem(contact));
}
return items;
}

ContactsPage

El último tipo de widget que necesitamos en el ContactsPage será el widget que contendrá el AppBar y el ContactList. Su implementación es la siguiente:

Tenemos que ContactsPage extiende de StatlessWidget por la misma razón vista anteriormente al no producirse cambios de estado en el widget. Y a la hora de crear el widget lo hacemos creando una instancia del Scaffold para tener un layout que nos ofrezca una zona para el AppBar y otra para la lista.

En este caso añadimos una AppBar como vimos en el anterior post al Scaffold y en el atributo body le pasamos una instancia de la lista de contactos siendo esta un widget ContactList. El ContactList lo creamos pasando la lista de contactos (kContacts) creada en el archivo contact_data.dart.

Y para terminar en el MaterialApp en su atributo home asignamos un nuevo ContactPage.

home: ContactsPage()

Ahora podemos lanzar nuestra app y ver la lista de contactos.

Contacts Page

Conclusión

Después de haber visto como crear una lista en Flutter podemos comparar con por ejemplo su misma implementación en Android.

En Android necesitaríamos dos xml. uno que contengan el AppBar y un RecycleView y otro para definir el layout del contacto. Además necesitaríamos por lo menos una Actividad o una Actividad más un Fragment, un Adapter y un ViewHolder.

La diferencia de código y de tiempo para crear lo mismo tanto en uno como en otro como hemos podido comprobar es bastante grande. Con este post por lo tanto ya podemos apreciar la potencia de Flutter.

En el siguiente post veremos como crear una arquitectura MVP (Model-View-Presenter) en Fluter.

El código de este tutorial corresponde al step 2 en el repo, si has tenido algún problema allí podrás encontrar el proyecto completo en la carpeta step2.

--

--