Widget ListView en Flutter
Índice de contenido
- Revertir lista + Scroll vertical/horizontal + bloquear scroll en el ListView
- Problema con el widget de ListView
- ListView animado en Flutter
- Crear un listview
- Animado
- Expandable ListView en Flutter
- Primeros pasos con el Exandable ListView en Flutter
- Crear un listado estático de Widgets en un Wrap/Row en base a un listado de objetos en Flutter
- ListView.builder y su equivalencia
- Listados estáticos: uso de Wrap en lugar de ListView.builder
- Ejemplo de listado dinámico con List.generate
- Filtros en Flutter: Cómo filtrar datos
- Filtro local: ejemplo con libros
- Switch para precio
- Filtro por categorías
- Widget para filtrar elementos individuales
- Filtro remoto: ejemplo con posts
- Conclusión
- De ListView a un GridView
- ListView
- GridView
- Ajuste del tamaño
- Parámetros opcionales
Un ListView es un widget en Flutter que se utiliza para construir una lista de widgets desplazables, y muy utilizamos junto con los Widget ScaffoldMessenger en Flutter para mostrar datos al interactuar con los items del listado, donde los elementos se agregan dinámicamente a medida que se desplaza la lista.
ListView es una herramienta poderosa para mostrar una gran cantidad de datos en una aplicación Flutter.
Flutter proporciona varios tipos de ListView para satisfacer diferentes necesidades y casos de uso, como ListView.builder, ListView.separated, ListView.custom, entre otros.
En resumen, ListView es un componente esencial en la construcción de interfaces de usuario en Flutter y se utiliza para mostrar una lista de datos de manera eficiente y dinámica; un ejemplo base de un ListView:
ListView.builder(
itemCount: 100, // número de elementos en la lista
itemBuilder: (BuildContext context, int index) {
// construir el elemento de la lista
return ListTile(
title: Text('Elemento $index'),
);
},
),En este ejemplo, utilizamos el constructor ListView.builder para construir una lista de 100 elementos. El parámetro itemCount indica el número de elementos que se mostrarán en la lista.
El parámetro itemBuilder especifica cómo construir cada elemento de la lista. En este caso, utilizamos un ListTile para cada elemento, con un título de texto que muestra el índice del elemento.
Este es solo un ejemplo sencillo, pero hay muchas formas posibles de personalizar y utilizar listas en Flutter, como agregar separadores, encabezados, pies de página, entre otros.
Vamos a conocer un widget fundamental para cualquier tipo de aplicación moderna en la cual queramos mostrar un conjunto de datos de manera organizada mediante una lista con scroll; este estupendo widget se conoce como el ListView y es similar al RecylverView de Android Studio pero más básico y sin optimización para listados largos pero mucho más sencillo de implementar que en Android con Kotlin/Java.
El código para implementar el mismo es así de simple:
ListView( children: <Widget>[ Text("Item ListView 1"), Text("Item ListView 2"), Text("Item ListView 3"), Text("Item ListView 4") ], )Como puedes ver, simplemente es un widgets llamado ListView que como viene siendo lo clásico o lo normal en esta clase de widget recibe una lista de widgets que pueden ser cualquier cosa, en este caso lo más sencillo en Flutter, que sería un widget de tipo texto.
Revertir lista + Scroll vertical/horizontal + bloquear scroll en el ListView
Hay muchas configuraciones que podemos realizar sobre el ListView mediante las propiedades, para indicar que queremos aplicar scroll en el eje horizontal o vertical, también podemos bloquear el scroll si necesitas hacer esto por algún motivo o revertir una lista; todo esto mediante una sola propiedad y por lo tanto mediante una línea de código.
Podemos configurar múltiples aspectos de nuestra lista, por ejemplo si quieres revertir los items, para eso empleamos la propiedad reverse, si quieres el scroll de manera vertical:
scrollDirection: Axis.verticalU horizontal:
scrollDirection: Axis.horizontalSi queremos bloquear el scroll en nuestra lista y quede fija en los primeros elementos:
physics: NeverScrollableScrollPhysics(),Pero por supuesto una lista de elementos fijos no nos sirve de absolutamente nada, la idea es hacer una lista dinámica de elementos; esto es ideal si nos conectamos a una Api Rest.
O un sistema similar, pero para poner todo simple, crearemos una función con un ciclo for que cree elementos de manera dinámica:
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: ListView(
children: generateItem(),
addAutomaticKeepAlives: false,
scrollDirection: Axis.vertical,
)
// This trailing comma makes auto-formatting nicer for build methods.
);
}
List<Widget> generateItem(){
final list = List<Widget>();
for (var i = 0; i <= 100; i++) {
list.add(Text("Item ListView "+i.toString()));
}
return list;
}También podemos colocar un divisor entre los elementos o items de nuestro widget de ListView:
for (var i = 0; i <= 100; i++) {
list.add(Text("Item ListView "+i.toString()));
list.add(Divider());
}Problema con el widget de ListView
El problema con el ListView tal cual lo implementamos, es que no está optimizado para trabajar con listas muy grandes, o listas dinámicas; recordemos que los ListView en Android básico fueron "reemplazados" en cierta medida por el RecyclerView los cuales ofrecen un desempeño excelente para grandes listas de elementos, ya que "reciclar" los items de vistas que no vemos y los vuelve a reutilizar en el resto del listado que vaya apareciendo o consumiendo bajo demanda del usuario.
Y con esto concluimos el uso del ListView al menos en su uso básico, pero recuerda que existe muchas más propiedades y variantes de este listado que iremos viendo a posterior.
Recuerda siempre revisar la documentación oficial en Flutter ListView.
Te voy a mostrar cómo puedes migrar un ListView a un Grid View y yo creo que la razón de esto sería sobre todo cuando tenemos una pantalla grande es decir no es un teléfono y en este caso queremos ir valga la redundancia de un ListView a un GridView para adaptar la cantidad de items en la pantalla en base al tamaño de la pantalla.
ListView animado en Flutter
En Flutter, ListView es un widget que es empleado oara mostrar un conjunto de elementos en una lista. ListView es un widget extremadamente flexible y permite mostrar una variedad de formatos así como listas en formato horizontal o vertical, con elementos personalizados o estándar. Además, ListView tiene un alto rendimiento y es ideal para grandes conjuntos de datos, ya que solo carga los elementos que se muestran actualmente en la pantalla.
Crear un listview
Para crear un ListView en Flutter, primero necesita un conjunto de datos sobre el que construir la lista. Luego, puede usar el widget ListView.builder para construir la lista dinámicamente según sea necesario, proporcionándole los elementos necesarios para mostrar en la lista a medida que el usuario se desplaza por ella:
ListView.builder(
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(items[index]),
);
},
);En este ejemplo, items es una lista de elementos que se mostrarán en la lista, y para cada uno de ellos se creará un ListTile, que contiene un título que muestra el texto del elemento.
Este es solo un ejemplo básico, hay muchas otras opciones y personalizaciones disponibles para ListView en Flutter.
Animado
Las animaciones son fundamentales en cualquier aplicación que construimos hoy en dia, dotar a la aplicación para mostrar cambios suaves o transiciones entre un estado a otro es algo normal; en los listados mediante los ListView en Flutter la cosa cambia un poco, ya que, los listados por su comportamiento, de iniciar la animación al aparecer un item en pantalla, se vuelve más complicado realizar dicha labor.
Existen muchas formas de animar un listado; pero, para mantenerlo simple, vamos a usar el siguiente paquete:
https://pub.dev/packages/delayed_display
Instalamos el paquete con:
pubspec.yaml
dependencies:
flutter:
sdk: flutter
syncfusion_flutter_datepicker:
delayed_display:El cual, permite agregar retrasos o delay el widget que sea embebido por el widget de DelayedDisplay(); además de esto, podemos especificar una sencilla animación tipo "fade In" la cual podemos personalizar la dirección de la animación indicando el eje por donde inicia el efecto; por ejemplo, si lo queremos de izquierda a derecha:
slidingBeginOffset: const Offset(-1, 0)O viseversa (derecha a izquierda):
slidingBeginOffset: const Offset(1, 0)De arriba a abajo:
slidingBeginOffset: const Offset(0, -1)O viseversa (de abajo a arriba):
slidingBeginOffset: const Offset(0, 1)Puedes personalizar otros aspectos como la curva de la animación entre otros detalles que puedes revisar en la documentación oficial.
Finalmente, usaremos el widget mencionado:
ListView.builder(
itemCount: 50,
itemBuilder: ((context, index) => DelayedDisplay(
delay: const Duration(milliseconds: 5),
slidingBeginOffset: const Offset(-1, 0),
fadeIn: true,
child: Card(***)- slidingBeginOffset, especificamos la curva de la animación mediante el Offset, el cual recibe la posición X y Y que son los factores tomados en cuenta para realizar el efecto de desplazamiento.
- fadeIn, habilita o deshabilita el efecto fade in.
- delay, indica el retraso en la animación.
Recuerda que esta publicación forma parte de mi curso completo sobre Flutter.
Expandable ListView en Flutter
Muchas veces cuando creamos nuestras aplicaciones en Android, iOS una aplicación en general, nos interesa crear un listado multinivel o un listado anidado, es decir, que teniendo el listado, si le damos un clic o toque se expanda y aparezca otro listado o al menos, más información, esto es algo complicado de crear si empleamos Android o iOS nativo pero con Flutter estamos de suerte y tenemos un widget que permite hacer este comportamiento.
El Expandable ListView es un widget en Flutter muy interesante y útil en muchos casos ya que permite crear listas desplegables con contenido oculto que es mostrado cuando le damos un click, así de simple.
Esta funcionalidad es especialmente útil cuando se necesita mostrar información adicional en una lista sin ocupar demasiado espacio en la pantalla.
Primeros pasos con el Exandable ListView en Flutter
El Expandable ListView se utiliza en conjunto con el widget ListView, que es responsable de mostrar los elementos del listado. Al utilizar el Expandable ListView, podemos ocultar o mostrar contenido adicional al hacer clic o toque en un elemento de la lista.
Una de las características más destacadas del Expandable ListView es su capacidad para expandirse y contraerse de forma animada. Esto crea una experiencia de usuario atractiva y mejora la usabilidad de la aplicación.
Para implementar el Expandable ListView, se deben seguir algunos pasos simples. Primero, creamos una lista de elementos que queremos mostrar en nuestra aplicación. Luego, utilizamos el widget ListView.builder para construir la lista y el widget Expandable ListView.builder para agregar la funcionalidad desplegable.
Dentro del widget Expandable ListView.builder, definimos cómo se comportará cada elemento de la lista cuando se expanda o contraiga. Podemos personalizar el contenido adicional que se mostrará al expandirse, como imágenes, texto o incluso otros widgets.
Además de la funcionalidad básica de expansión y contracción, el Expandable ListView también ofrece opciones de personalización. Podemos ajustar la apariencia de los encabezados y los íconos utilizados para indicar el estado de cada elemento de la lista.
El Expandable ListView en Flutter es una herramienta poderosa para crear interfaces de usuario dinámicas y atractivas. Permite a los desarrolladores mostrar información adicional de manera efectiva en una lista sin abrumar al usuario con demasiada información de una sola vez.
Veamos un ejemplo
ExpansionTile(
title: Text('Título del elemento'),
children: <Widget>[
ListTile(
title: Text('Element 1'),
),
ListTile(
title: Text('Element 2'),
),
ListTile(
title: Text('Element 3'),
),
],
)El ExpansionTile tiene características similares a los del ListTile como el título, subtítulo, puedes emplear la opción de ayuda de VSC o Android Studio para ver más información.
Aquí te doy otro ejemplo en el cual, muestro como crear un listado de listado que era el objetivo original de esta publicación:
ListView.builder(
shrinkWrap: true,
itemCount: widget.tutorialModel.tutorialSectionsModel.length,
itemBuilder: (context, index) {
return ExpansionTile(
title: Text('TEXT'),
subtitle: Text('TEXT'),
children: [
ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (context, index2) {
return ListTile(
title: Row(
children: [
Checkbox(
value: true,
onChanged: (value) {},
),***
);
},
)
],
);
},
)Como puedes apreciar, ya que, el ExpansionTile recibe un children o conjunto de widgets, podemos colocar una columna y como elemento único otro Listview y con esto, tenemos un Listview de Listview en Flutter.
Crear un listado estático de Widgets en un Wrap/Row en base a un listado de objetos en Flutter
Te quiero mostrar cómo puedes crear un listado. No me refiero al listado tipo ListView o ListView.builder, que es el que estamos viendo aquí en pantalla:
ListView.builder(
itemCount: bookResponseModel.books.length,
itemBuilder: (_, int position) {
return _itemBook(position, context);
}
)ListView.builder y su equivalencia
El ListView.builder recuerda un poco al RecyclerView en Android nativo. Lo que hace es reciclar los items que no se ven en pantalla para mostrarlos nuevamente cuando sea necesario.
Por ejemplo, si bajamos la lista, los elementos que se ocultan en la parte superior se reutilizan más abajo, cambiando únicamente la información que muestran. Esto es más eficiente que crear un montón de widgets en memoria que nunca se ven.
Nota: No vengo a profundizar en esto; solo recordemos que ListView.builder está pensado para listados dinámicos y grandes.
Listados estáticos: uso de Wrap en lugar de ListView.builder
Para listados estáticos, como un listado de categorías que no requiere scroll dinámico ni reciclaje de elementos, no es recomendable usar ListView.builder. Esto sería ineficiente, porque no necesitamos verificar constantemente si un item está visible u oculto.
En este caso, puedes construir un listado usando un Wrap, que adapta el contenido automáticamente y funciona como un equivalente a Row y Column combinados:
Wrap(
spacing: 1,
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.start,
children: categories
.map((c) => TextButton(
child: Text(
c.title,
style: TextStyle(
color: _categoryId == c.id
? Colors.purple
: Theme.of(context).colorScheme.secondary,
fontWeight: _categoryId == c.id
? FontWeight.bold
: FontWeight.w500),
),
onPressed: () {
if (_categoryId == c.id) {
_categoryId = 0;
} else {
_categoryId = c.id;
}
setState(() {});
_filter();
},
))
.toList(),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(LocaleKeys.close.tr()),
),
Wrap coloca los widgets en filas y columnas automáticamente.
children recibe una lista de widgets, que en este caso se genera a partir de un listado de objetos.
Con el método map, convertimos cada objeto (por ejemplo, cada categoría) en un widget, en este caso un TextButton.
Ejemplo de listado dinámico con List.generate
También podemos crear widgets a partir de un listado de manera dinámica usando List.generate:
List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headlineSmall,
),
);
});
Esto permite generar un listado de widgets basado en cualquier cantidad de elementos.
Es útil para listados grandes donde quieres crear widgets de manera programática.
Si quieres, puedo hacer una versión resumida y visual con un diagrama de Wrap vs ListView.builder, para que se entienda mucho más rápido cómo y cuándo usar cada uno.
Filtros en Flutter: Cómo filtrar datos
Te voy a explicar algo que considero muy interesante: el uso de filtros para filtrar datos en Flutter.
En este caso, como puedes ver en pantalla, este componente puede colocarse en cualquier parte. Si has seguido un poco la aplicación, ya sabrás que en la parte de los posts, donde lo tengo colocado arriba, el espacio es reducido y mostrar tanta información en una sola pantalla puede complicar la organización.
Por eso prefiero aprovechar las características de los dispositivos móviles: colocar el filtro en un botón accesible, generalmente en la parte inferior para mayor comodidad al usarlo con el pulgar. Por ahora está colocado aquí y funciona correctamente.
Filtro local: ejemplo con libros
Fíjate que aquí estamos trabajando con libros. Tengo un número limitado de registros, entre 15 y 30 libros, por lo que la ordenación es local, y extremadamente rápida. Más adelante te muestro cómo sería si los filtros se realizan de manera remota, en un servidor.
Switch para idioma
Aquí empleo un Switch para filtrar por idioma:
ListTile(
leading: const Icon(Icons.language, color: Colors.purple),
title: const Text('Solo en español'),
trailing: Switch.adaptive(
value: _onlyLang == 'spanish',
activeColor: Colors.purple,
onChanged: (value) {
_onlyLang = 'spanish';
_filter();
setState(() {});
}),
),
ListTile(
leading: const Icon(Icons.language, color: Colors.purple),
title: const Text('Only in english'),
trailing: Switch.adaptive(
value: _onlyLang == 'english',
activeColor: Colors.purple,
onChanged: (value) {
_onlyLang = 'english';
_filter();
setState(() {});
}),
),
_onlyLang guarda el idioma seleccionado como un String (spanish o english).
Al cambiar el switch, se actualiza automáticamente mediante setState().
Switch para precio
Para filtrar por precio (gratis o pago), utilizo otro switch:
ListTile(
leading: const Icon(Icons.exposure_zero, color: Colors.purple),
title: Text(LocaleKeys.free.tr()),
trailing: Switch.adaptive(
value: _freePay == 'free',
activeColor: Colors.purple,
onChanged: (value) {
_freePay = (_freePay == 'free') ? '' : 'free';
setState(() {});
_filter();
}),
),
ListTile(
leading: const Icon(Icons.payments, color: Colors.purple),
title: Text(LocaleKeys.pay.tr()),
trailing: Switch.adaptive(
value: _freePay == 'pay',
activeColor: Colors.purple,
onChanged: (value) {
_freePay = (_freePay == 'pay') ? '' : 'pay';
setState(() {});
_filter();
}),
),- _freePay controla tres estados: gratis, pago o ninguno.
- La lógica se maneja con condicionales que permiten alternar entre los valores correctamente.
Filtro por categorías
Para las categorías, empleo un Wrap que adapta los botones según el espacio disponible:
Wrap(
spacing: 1,
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.start,
children: categories
.map((c) => TextButton(
child: Text(
c.title,
style: TextStyle(
color: _categoryId == c.id
? Colors.purple
: Theme.of(context).colorScheme.secondary,
fontWeight: _categoryId == c.id
? FontWeight.bold
: FontWeight.w500),
),
onPressed: () {
_categoryId = (_categoryId == c.id) ? 0 : c.id;
setState(() {});
_filter();
},
))
.toList(),
),- _categoryId almacena la categoría seleccionada.
Cada botón actualiza el estado y ejecuta la función _filter() para mostrar solo los elementos correspondientes.
Widget para filtrar elementos individuales
Para cada elemento (libro), utilizo un widget que verifica si debe mostrarse:
Widget _itemBook(int position, BuildContext context) {
final book = bookResponseModel.books[position];
if (!book.show) {
return const SizedBox();
}
String image = '';
if (book.post.image != '') {
image = '${BlogHelper.baseUrlImage}${book.post.path}/${book.post.image}';
}
return Column(
children: [
// Contenido del libro
],
);
}- La propiedad show determina si el elemento se muestra o se oculta.
- Esto evita modificar directamente el array y es más eficiente que eliminar o agregar elementos continuamente.
Filtro remoto: ejemplo con posts
Cuando trabajamos con muchos posts, el filtro local no es eficiente. En ese caso, se realiza un filtro remoto:
Cada vez que el usuario selecciona un filtro, se envía una petición al servidor.
El servidor devuelve el listado paginado según los filtros seleccionados.
Así se evita cargar todos los registros de golpe, mejorando la eficiencia.
_dataList() async {
bookResponseModel = await AcademyHelper.getMyBooks(appModel.userToken);
}Esta función obtiene los datos filtrados desde el servidor.
La lógica de filtrado y paginación se aplica directamente en el backend.
Conclusión
- Los filtros locales son rápidos y adecuados para listados pequeños.
- Los filtros remotos son necesarios cuando trabajamos con grandes cantidades de datos.
- Se pueden combinar filtros de idioma, precio y categoría de manera eficiente.
- La implementación con Wrap, Switch y condicionales permite un control claro y modular de la visualización de los elementos.
De ListView a un GridView
ListView
Tenemos un listado no importa aquí el nombre es un listado de cualquier cosa preguntamos por el y esto es para saber la cantidad de elementos que vamos a construir luego aquí tenemos el item builder en la cual recibimos el contesto no me interesa en este caso y la posición y aquí finalmente un widget que construye nuestro item en este caso que es esto que tenemos aquí esto no tiene mucha pérdida y es el mismo que estoy empleando por acá simplemente aquí algunas condiciones para
saber si la imagen existe:
ListView.builder(
itemCount: tutorialResponseModel.tutorials.length,
itemBuilder: (_, int position) {
return _itemTutorial(position, context);
}),Y demás ya eso es cuestión tuya una columna para bueno encolar nuestros elementos que en este caso es el título un espaciado y la imagen aquí le metí el ClipRRect para hacerle un redondeado en las esquinas por lo demás no tiene absolutamente nada de raro y un botoncito para ir a la acción a comprar o lo que sea esto lo podemos ampliar sin ningún cambio en ambos elementos si es un ListView o un GridView:
Widget _itemTutorial(int position, BuildContext context) {
final appModel = Provider.of<AppModel>(context, listen: false);
final tutorial = tutorialResponseModel.tutorials[position];
if (!tutorial.show) {
return const SizedBox();
}
String image = '';
if (tutorial.image != '') {
image = '${AcademyHelper.baseUrlImage}${tutorial.path}/${tutorial.image}';
}
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
tutorial.title.toUpperCase(),
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(
height: 15,
),
image != ''
? ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image.network(
image,
errorBuilder: (context, error, stackTrace) =>
const SizedBox(),
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Container(
width: double.infinity,
height: 120,
color: Colors.grey,
);
},
),
))
: const SizedBox(),
const SizedBox(
height: 15,
),
Padding(
padding: const EdgeInsets.only(right: 15, left: 15),
child: Text(
truncate(tutorial.description),
style: Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(
height: 15,
),
Text(
'${tutorial.priceOffers}\$',
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
color: Colors.green, fontWeight: FontWeight.bold),
),GridView
Tal cual te mostraba entonces qué tenemos aquí en el GridView ya que sabemos qué es lo que tenemos aquí en el ListView:
GridView.builder(
shrinkWrap: true,
physics:
const BouncingScrollPhysics(), // evita problema de doble scroll
padding: const EdgeInsets.all(8),
itemCount: tutorialResponseModel.tutorials.length,
gridDelegate:
// SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: countItem,
// ),
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: countItem,
crossAxisSpacing: 8.0,
mainAxisExtent: 520,
mainAxisSpacing: 8.0),
itemBuilder: (_, position) {
return _itemTutorial(position, context);
})Y lo podemos comparar esto sería para hacerlo un poquito más eficiente tal cual te indica por acá esto sería un poco opcional pero en este caso como en varias vistas yo tengo doble scroll es decir por una parte en esta vista creo que no tengo pero si esto estoy empleando como elemento padre un single child scroll View y este también tiene su propio scroll entonces para evitar precisamente un problema con el doble scroll:
physics: const BouncingScrollPhysics(), // evita problema de doble scrollEsto es para definir el tamaño de nuestra celda del gripView:
mainAxisExtent: 520,Sería del elemento del item como lo quieras ver unos espaciados:
crossAxisSpacing: 8.0,
mainAxisSpacing: 8.0Para que no aparezcan todos pegados ya esto sería cuestión tuya personal y por aquí le pasamos la posición para que construya en base al listado que lo tenemos obviamente definido a nivel de la clase construye el elemento tal cual te mostraba aquí la parte creo que más resalta es el Main Access extended que es para indicar el tamaño de la celda:
mainAxisExtent: 520,Fíjate que, por más espacio disponible que haya, es recomendable definir un tamaño mínimo para cada celda o fila. Esto asegura que todas las filas estén alineadas correctamente y evita problemas de diseño.
Si asignamos un tamaño menor al necesario, podemos tener problemas de overflow, ya que la celda o el contenedor donde colocamos nuestros elementos será demasiado pequeño. Esto puede generar que el contenido se desplace hacia arriba, algo que obviamente no queremos.
Ajuste del tamaño
Para evitar estos problemas, es recomendable jugar con el tamaño mínimo que se asigna a cada celda. Esto es opcional, pero si no lo defines, puedes encontrarte con el problema que mencionamos anteriormente: contenido desordenado, celdas demasiado pequeñas y un aspecto visual poco profesional.
Parámetros opcionales
Existen parámetros adicionales que puedes configurar, dependiendo de tus necesidades. Por ejemplo, algunos ajustes son opcionales y puedes buscar más información en internet sobre qué otros parámetros se pueden aplicar.
Si no defines un tamaño mínimo, no dará un error, pero el contenido aparecerá comprimido y se verá desordenado.
Al definir un tamaño mínimo, solucionamos el problema de overflow y aseguramos que la presentación de las filas sea consistente y legible.
En resumen, asignar un tamaño mínimo a cada celda es una práctica recomendable para mantener la estructura y evitar problemas de desplazamiento del contenido.
Siguiente paso, aprende a usar el widget FutureBuilder en Flutter.
Acepto recibir anuncios de interes sobre este Blog.
Vamos a conocer como podemos crear un listado en Flutter con el widget de ListView en Flutter: Para mostrar datos empleando el widget de ListView., también te mostraré como emplear el sistema de GridView en Flutter partiendo de un ListView, animarlos y la opción de expandir.