Flutter Widget Diseño de pantallas
Sumario
Introducción
- En las secciones anteriores vimos algunos de los widgets que podemos emplear para visualizar contenidos en una pantalla.
- En esta sección vamos a ver widgets que nos permiten colocar a otros widgets en ciertas posiciones en base a las propiedades que disponga el Widget.
- Vienen a ser el equivalente a divs en HTML.
- Asociado a este punto vamos a ver como identificar y solucionar los problemas que podamos tener de posicionamiento cuando los widgets no queppan en el espacio asignado por su widget contenedor.
Column / Row
- Más información en:
- Estos widgets permiten 'colocar' en forma de fila o columna el cojunto de Widget que se encuentran dentro.
- El widget Column coloca los widgets uno debajo del otro (en una línea vertical)
- El widgert Row coloca los widgets uno al lado del otro (en una línea horizontal).
- No poseen Scroll y por lo tanto los Widgets que lo conforman no deberían ocupar más espacio que el espacio del contenedor donde se encuentren.
- En caso de necesitar un scroll tendríamos que hacer uso de un Widget ListView como ya vimos en la sección anterior.
- Creamos una nueva página en la carpeta pages de nombre columnrow_page.dart
- En todas las páginas haremos lo mismo:
- Importamos la librería de 'material' (recordar que existe un snippet que lo hace automático).
- Creamos una clase (ColumnRowPage) que derive de StatelessWidget (al hacerlo será necesario implementar el método build, ya os da un aviso el Android Studio).
- Los parámetros más usados son:
- children[]: Conjunto de Widget que van a aparecer visualmente.
- MainAxisAlignment: Indicamos como van a posicionarse los children con respecto al eje principal.
- En el caso de Column, el eje principal es el vertical y en el caso de Row, es el eje horizontal.
- CrossAxisAlignment: Indicamos como van a posicionarse los children con respecto al eje perpendicular al principal.
- En el caso de Column, el eje Cross es el horizontal y en el caso de Row, es el eje vertical.
- Veamos una imagen en la que va a quedar más claro a que se refiere cada eje en cada caso:
- Veamos un ejemplo sencillo en el que emplearemos un Column para colocar texto visualmente en forma de filas (recordar que Column coloca a los widget en una línea vertical).
- Dejamos los valores por defecto para cada eje y veremos que los elementos empiezan a colocarse en la parte superior (MainAxisAlignment.start) y horizontalmente están centrados con respecto al espacio que ocupan (CrossAxisAlignment.center), cogiendo como referencia la fila que ocupa más ancho)
import 'package:flutter/material.dart'; class ColumnRowPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Ejemplo de uso de Row y Colum'), ), body: Column( children: [ Text('Texto de la primera fila',style: TextStyle(backgroundColor: Colors.yellow),), Text('Texto de la segunda fila. Este texto es más largo.',style: TextStyle(backgroundColor: Colors.red),), Text('Texto de la tercera fila',style: TextStyle(backgroundColor: Colors.brown),), ], ) ); } }
- Ahora veamos un ejemplo modificando alguno de los parámetros de los ejes:
import 'package:flutter/material.dart'; class ColumnRowPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Ejemplo de uso de Row y Colum'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text('Texto de la primera fila',style: TextStyle(backgroundColor: Colors.yellow),), Text('Texto de la segunda fila. Este texto es más largo.',style: TextStyle(backgroundColor: Colors.red),), Text('Texto de la tercera fila',style: TextStyle(backgroundColor: Colors.brown),), ], ) ); } }
- Como en Html, estos widgets son 'contenedores' y podemos tener como parte de un children otro contenedor, por lo tanto podemos tener dentro de Row y Column, otros Row y Column de forma anidada...
- Veamos un ejemplo.
- Fijarse que por defecto, tanto Row como Column toman como 'referecia' el widget que ocupa más espacio.
- En el siguiente ejemplo, el Widget Row está alineado en el CrossAxis al final (CrossAxisAlignment.end) y como uno de los iconos es más alto, el resto se sitúa en la parte baja del mismo.
import 'package:flutter/material.dart'; class ColumnRowPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Ejemplo de uso de Row y Colum'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text('Texto de la primera fila',style: TextStyle(backgroundColor: Colors.yellow),), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ Icon(Icons.favorite, size: 50,), Icon(Icons.audiotrack, size: 100,), Icon(Icons.cast, size:50,), ], ), Text('Texto de la tercera fila',style: TextStyle(backgroundColor: Colors.brown),), ], ) ); } }
Expanded
- Asociado al widget Row y Column se suele utilizar el widget Expanded, que permite 'expandir' el tamaño del widget hasta el tamaño de su contenedor en su MainAxis.
- Recordar que en Android Studio y en otros ide´s podéis 'envolver' un Widget con otro Widget, situándonos sobre él y pulsando las teclas ALT+Enter aparece la opción Wrap...
- Entre los parámetros a enviar tenemos:
- child: Es el widget que queremos que se expanda. Obligatorio.
- flex: Este parámetro es equivalente a emplear un LinearLayout en Android Studio. Cuando tenemos varios widget´s que se expanden, permite darle un peso a cada uno de ellos para hacer que uno ocupe más que el otro.
- Veamos un ejemplo:
- En este caso, estamos expandiendo en el widget Column, el widget Row para que ocupe todo el espacio entre los dos textos.
- Por otro lado, dentro del Row, estamos expandiendo dos iconos y hacemos que el grande ocupe 3/6 partes del espacio de la fila y el icono de la derecha las 2/6 partes.
- Para poder visualizar el espacio que están ocupando, envolví el Widget Icon con un Container, que explicaré en las siguientes secciones y que nos permite establecer un color de fondo.
import 'package:flutter/material.dart'; class ColumnRowPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Ejemplo de uso de Row y Colum'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text('Texto de la primera fila',style: TextStyle(backgroundColor: Colors.yellow),), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded(child: Container(child: Icon(Icons.favorite, size: 50,),color: Colors.yellow,),flex: 1,), Expanded(child: Container(child: Icon(Icons.audiotrack, size: 100,),color: Colors.blue),flex:3), Expanded(child: Container(child: Icon(Icons.cast, size:50,),color: Colors.red,),flex: 2,), ], ), ), Text('Texto de la tercera fila',style: TextStyle(backgroundColor: Colors.brown),), ], ) ); } }
- Nota: Como podéis comprobar Expanded sólo afecta el eje principal. Si quisiérais que un icono ocupe todo el alto disponible, podéis modificar la propiedad height del Container y darle el valor double.infinity.
Align / Center
- Más información en:
- Normalmente son usados cuando queramos centrar o alinear un único widget.
Container
- Padding y margin: https://api.flutter.dev/flutter/widgets/Padding-class.html
- Modificar el tamaño del contenedor. Empleado en Row y Column
SizeBox
Debugger Diseño
- Debugger de diseño. Verificar el tamaño de las cajas de cada widget y localizar cual de ellas produce un error
Enlaces de interés
- https://flutter.dev/docs/development/ui/layout
- https://esflutter.dev/docs/development/ui/layout#organiza-multiples-widgets-vertical-y-horizontalmente
- https://medium.com/comunidad-flutter/construya-uis-responsivas-en-flutter-f528d16b50a4
- https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434
- https://medium.com/flutter-community/build-responsive-uis-in-flutter-fd450bd59158
Enlace a la página principal de la UD3
Enlace a la página principal del curso
-- Ángel D. Fernández González -- (2021).