Listas y mallas
Introducción
Hay un elemento muy importante que aún no se ha abordado en el libro. ¿Cómo hacer que aparezcan las colecciones?
La exposición de una gran cantidad de elementos en pantalla nunca es obvia y puede ser la fuente de muchos problemas. Para cubrir estas necesidades, el equipo de Flutter proporciona dos widgets que son muy complementarios.
El primero es ListView que, como su nombre indica, permite que una colección se muestre como una lista. El capítulo discutirá varias formas de implementar este widget, así como diferentes métodos de presentación de los ítems.
El segundo widget es GridView. Su nombre también es muy explícito. Esta vez, ya no se trata de una vista de lista, sino de una cuadrícula o malla. Esta estará compuesta por celdas, que también pueden tomar diferentes formas.
ListView
ListView es una herramienta muy útil para mostrar una gran cantidad de información en pantalla. En el capítulo anterior, se mencionaron rápidamente los errores relacionados con los desbordamientos. Volviendo a este punto, si la cantidad de información que se debe mostrar excede el tamaño de la pantalla, se produce un error. Para remediar esto, se utilizó un widget SingleChildScrollView. Sin embargo, no es una solución duradera.
Por tanto, la solución recomendada es utilizar ListView. Tal como está, el constructor le permite insertar una lista de widgets hijos. Esta solución es ideal para listas cortas. De hecho, todos los hijos, visibles o no, se construirán desde el principio. Esta carga puede resultar muy pesada si la lista es larga.
1. ListView.builder
Para mayores cantidades de información, es mejor usar el constructor llamado ListView.builder. Se necesita un parámetro de tipo IndexedWidgetBuilder, que creará los hijos a demanda, a medida que se hagan visibles, mientras se desplaza por la lista. Este es el widget que usará el siguiente ejemplo.
Pero antes conviene detallar un poco los elementos que permitirán construir este ListView.
En el constructor con nombre, solo hay un parámetro obligatorio llamado itemBuilder. Como se mencionó anteriormente, este espera una instancia de la clase IndexedWidgetBuilder. Este widget requiere dos elementos: un BuildContext y un index.
El segundo parámetro importante a considerar, es itemCount. Permite definir el tamaño de la ListView.
Antes de configurar esto, necesita tener una colección. Para ello, se crea una clase Coche. Toma una forma simple y solo tiene tres atributos marca, modelo e imagen, además de un constructor:
class Coche {
String marca;
String modelo;
Image imagen;
Coche(this.marca, this.modelo, this.imagen);
}
La aplicación es clásica. La clase MyHomePage extenderá StatefulWidget. Teóricamente, una ListView se puede implementar sin administración de los estados. Sin embargo, también se utilizará otro widget actualmente desconocido. Se trata de una sorpresa que se mencionará poco después.
Mientras tanto, se declara una lista de coches al comienzo de la clase _MyHomePageState. Esta...
GridView
Las cuadrículas o mallas son otra forma de mostrar colecciones. A diferencia de ListView, el widget GridView permite la visualización como miniaturas. Por tanto, el efecto es diferente, pero en el caso de que haya imágenes o iconos en la colección, este tipo de presentación es más rentable.
1. GridView.builder
Al igual que con las listas, un constructor llamado GridView.builder permite la implementación del widget más fácilmente. Sin embargo, tenga en cuenta que hay un parámetro a tener en cuenta, gridDelegate. Le permite elegir en particular el número de columnas en las que se distribuirán las miniaturas. En el código que servirá de ejemplo, siempre con los coches, el parámetro gridDelegate recibirá una instancia de SliverGridDelegateWithFixedCrossAxisCount que permite definir un número fijo de columnas. En este caso concreto, se establecerá en 3. Para el resto, estarán presentes los parámetros itemCount e itemBuilder, y funcionarán de la misma forma que en el resto de casos prácticos.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
backgroundColor: Colors.cyan,
),
body:...