Flutter Widget Diseño de pantallas

De MediaWiki
Revisión del 18:04 19 oct 2024 de Angelfg (discusión | contribuciones) (→‎Container)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegación Ir a la búsqueda

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 quepan 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).
Flutter dart colrow 1.JPG
Imagen obtenida de este sito web


  • 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 o de un SingleChildScrollView.


  • 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:
Flutter dart colrow 3.JPG



  • 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)
Flutter dart colrow 2.JPG


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:
Flutter dart colrow 4.JPG


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),),

          ],
        )
    );
  }
}


En este ejemplo hacemos que el contenido se centre en su eje principal (verticalmente). Funciona debido a que el Column se expande en su eje main.
Por otra parte, en su eje cross (horizontalmente) al usar textos, estos hacen que el espacio que reserva el row se adapte al tamaño de los mismos (no los expande) y por eso al situarlos al final horizontalmente, lo hacen con respecto al texto más largo. Si rodeamos el Column con un Container y le damos un ancho, la alineación la harían con respecto al tamaño en ancho de dicho container.


  • 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.


Flutter dart colrow 5.JPG
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),),

          ],
        )
    );
  }
}



Rows y Columns con widget que se expanden

  • Row no tiene límite en su eje main axis (horizontal) y por eso si ponemos muchos elementos podemos quedarnos sin espacio.
Verticalmente intenta darle el espacio que necesita y si el children se expande (como un Container) le dará todo el espacio vertical hasta su contenedor padre.
Column no tiene límite en su eje main axis (verticalmente) y por eso si ponemos muchos elementos podemos quedarnos sin espacio.
Horizontalmente intenta darle el espacio que necesita y si el children se expande (como un Container) le dará todo el espacio horizontal hasta su contenedor padre.


  • Imaginemos que tenemos un row con un listview en su interior con la dirección de scroll horizontal (os dará un error):
    return Scaffold(
      appBar: AppBar(
        title: const Text('ROWS_COLS'),
      ),
      body: Row(
        children: [
            ListView(
              scrollDirection: Axis.horizontal,
              children: [
                Text('1111111'),
                Text('2222222'),
                Text('3333333'),

        ],
      ),
    );
¿ Por qué es necesario un width en la lista ?
Porque en el eje main axis del Row no se establece límites y por tanto la lista se intenta expandar horizontalmente para poder añadir sus elementos y al no encontrar límites nos dará un error. Por lo tanto, siempre deberemos poner un límite en el eje de scroll de una lista cuando se encuentre dentro de un row/column
Verticalmente (que es el Cross Axis del Row) no tenemos problema ya que la lista se va a expandir hasta lo máximo que permite su padre que es el scaffold (en este ejemplo)
    return Scaffold(
      appBar: AppBar(
        title: const Text('ROWS_COLS'),
      ),
      body: Row(
        children: [
          Container(
            width: 100,
            color: Colors.blue,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: [
                Text('1111111'),
                Text('2222222'),
                Text('3333333'),

              ],
            ),
        ],
      ),
    );
  • Cambiemos ahora la orientación del scroll de la lista a vertical (dará un error):
    return Scaffold(
      appBar: AppBar(
        title: const Text('ROWS_COLS'),
      ),
      body: Row(
        children: [
            ListView(
              scrollDirection: Axis.vertical,
              children: [
                Text('1111111'),
                Text('2222222'),
                Text('3333333'),

        ],
      ),
    );


En este caso necesitamos establecer limitaciones en el ancho y en el alto. ¿ Por qué ?
En el alto ya que la lista se va a expandir para dar espacio a los elementos que va a añadir (verticalmente) y no tiene un límite de espacio establecido.
En el ancho ya que la lista también se expande horizontalmente, pero a diferencia del caso anterior, al estar dentro de un row no tiene límite horizontal al ser el main axis del row.


    return Scaffold(
      appBar: AppBar(
        title: const Text('ROWS_COLS'),
      ),
      body: Row(
        children: [
          Container(
            width: 100,
            height: 200,
            color: Colors.blue,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: [
                Text('1111111'),
                Text('2222222'),
                Text('3333333'),

              ],
            ),
        ],
      ),
    );



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.
Flutter dart colrow 6.JPG
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.



Spacer


  • Asociado a los Widget Row y Column, podemos hacer uso de este widget para establecer una separación entre los widgets que conforman el Row/Column.
Parámetros a emplear => Parámetro flex:
  • Si no empleamos el parámetro flex, cogerá el espacio en blanco total que encuentre en el MaixAxis.
  • Si explemamos el parámetro flex, dividirá el espacio vacío total en el MainAxis por la suma de todos los Spacer que encuentre con sus respectivos flex (si no se establece tendrá el valor de 1) y asignará a cada Spacer el número flex indicado.


Veamos un ejemplo:
Flutter dart colrow 7.JPG
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: [
            Row(
              children: [
                Icon(Icons.favorite, size: 30,),
                Spacer(flex: 3,),
                Icon(Icons.audiotrack, size: 30,),
                Spacer(flex: 2,),
                Icon(Icons.cast, size:30,),
                Spacer(flex: 2,),
                Icon(Icons.access_alarm, size:30,),
              ],
            ),

          ],
        )
    );
  }
}



Container


  • Creamos una nueva página en la carpeta pages de nombre container_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 (ContainerPage) que derive de StatelessWidget (al hacerlo será necesario implementar el método build, ya os da un aviso el Android Studio).


  • Contenedor que permite 'envolver' cualquier widget y con el cual podemos establecer un tamaño, padding, margin, color de fondo y borde entre otras propiedades.
La diferencia entre margin y padding es la misma que en HTML con sus div´s.
Todos los contenidos conforman un contenedor de forma rectangular que lo rodea. El marign es el espacio que hay entre dos contenedores y el padding es el espacio que hay entre el contenido y su contenedor. Más información en este enlace.
PDM UI 9.jpg
En color rojo tenemos el padding y en color verde tenemos el margin



Al establecer un margin y un padding podemos indicar en qué dirección queremos que se aplica esa modificación.
Para facilitarnos el establecer estos valores haremos uso de la clase EdgeInsets que permite emplear diferentes métodos:
  • all: establece un margin-padding en todas las direcciones.
  • symmetric: establece un margin-padding simétrico, es decir, se envían dos valores, uno de ellos establece el margin-padding inferior y superior y otro establece el margin-padding derecho e izquierdo.
  • only: indicamos sobre que lados vamos a establecer el margin-padding.


Nota importante:
  • Si tenemos un contenedor dentro de otro contenedor, el contenedor interior se expandirá hasta ocupar todo el espacio del contenedor padre. Por lo tanto si intentamos alinear el contenido no funcionará. Debemos establecer un tamaño más pequeño en el contenedor hijo y desde el contenedor padre, donde debe situarse el contenedor hijo con la propiedad alignment.
  • Se un contenedor tiene la propiedad alignmet, el child del mismo se situará en lo indicado por alignment .
Container(
               margin: EdgeInsets.all(10.0),   // Establece un margin de 10 en todas las direcciones
               alignment: Alignment.center,    // Expande y centra
               color: Colors.yellow,
               child: Text('CONTENEDOR 3'),
)


Al poner alignment, debe de posicionar el contenedor con respecto a su contenedor padre por lo que debe determinar que tamaño tiene. En ese caso se expandirá hasta encontrar un límite.


  • Veamos un ejemplo.
En este caso voy a hacer uso de la clase MediaQuery para obtener información del ancho de la pantalla y así poder establecer un ancho de uno de los contenedores en base a un porcentaje de dicho ancho.
Flutter dart container 1.JPG


import 'package:flutter/material.dart';

class ContainerPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Ejemplo de contenedores'),
        ),
        body: _conjuntoContenedores(context)  // Le pasamos el context para establecer un ancho en porcentaje de la pantalla, lo necesita la clase MediaQuery
    );
  }

  Widget _conjuntoContenedores(BuildContext context){
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Container(
          width: double.infinity,                 // De ancho todo el espacio disponible
          height: 50.0,
          color: Colors.red,
          margin: EdgeInsets.only(bottom: 20.0),  // Establece un margin sólo en la parte inferior
          padding: EdgeInsets.all(10.0),          // Establece un padding en las cuatro direcciones
          child: Text('CONTENEDOR 1',textAlign: TextAlign.center,),
        ),
        Expanded(
          flex: 2,
          child: Container(
            padding: EdgeInsets.only(top:20.0,left: 20.0),
            margin: EdgeInsets.only(top: 30.0),
            width: MediaQuery.of(context).size.width*0.5,
            color: Colors.blue,
            child: Text('CONTENEDOR 2'),
          ),
        ),
        Expanded(
          flex: 2,
          child: Container(
            margin: EdgeInsets.all(10.0),   // Establece un margin de 10 en todas las direcciones
            alignment: Alignment.center,    // Expande horizontalmente y centra
            color: Colors.yellow,
            child: Text('CONTENEDOR 3'),
          ),
        ),

      ],
    );

  }
}



  • El widget Container también tiene entre sus propiedades un constraint de tipo BoxContraints, con lo que podemos establecer un ancho y alto al igual que hacemos con width - height. La diferencia es que de esta forma el tamaño del contenedor puede variar entre un max-min.
          Container(

            constraints: BoxConstraints(
              maxHeight: 100,
              maxWidth: 100,
              minHeight: 50,
              minWidth: 50,
            ),
            color: Colors.red,
          ),



Align / Center

  • Más información en:


  • Creamos una nueva página en la carpeta pages de nombre aligncenter_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 (AlignCenterPage) que derive de StatelessWidget (al hacerlo será necesario implementar el método build, ya os da un aviso el Android Studio).



  • Normalmente son usados cuando queramos centrar o alinear un único widget. La diferencia entre Align y Center es que con Align podemos establecer donde situar al Widget dentro de su contenedor (arriba-abajo, izquierda-derecha) mientras que con Center siempre lo va a centrar.


Flutter dart container 2.JPG
import 'package:flutter/material.dart';

class AlignCenterPage extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Ejemplo de Align y Center'),
        ),
        body: _conjuntoContenedores()
    );
  }
  
  Widget _conjuntoContenedores(){
    return Column(
      children: [
        Center(
          child: Container(
            height: 150.0,
            width: 150.0,
            color: Colors.yellow,
            child: Center(child: Icon(Icons.access_alarm,size: 40.0,)),
          ),
        ),
        Align(
          alignment: Alignment.centerRight,     // Es igual que sea top o botton. Sólo hace uso del right al usar Column
          child: Container(
            height: 150.0,
            width: 150.0,
            color: Colors.red,
            child: Align(
              alignment: Alignment.bottomLeft,  // Sitúa al icono abajo a la izquierda con respecto a su contenedor
              child: Icon(Icons.ac_unit,size: 40.0,),
            ),
          ),
        ),
        Expanded(
          child: Container(                         // Creo un container que ocupe todo el espacio restante
            color: Colors.brown,
            child: Align(
              alignment: Alignment.bottomRight,     // Mueve el container verde abajo a la derecha
              child: Container(
                height: 150.0,
                width: 150.0,
                color: Colors.green,
                child: Align(
                  alignment: Alignment.bottomLeft,  // Mueve el icono dentro del contenedor verde, abajo a la izquierda
                  child: Icon(Icons.ac_unit,size: 40.0,),
                ),
              ),
            ),
          ),
        ),



      ],

    );
  }
}



SizedBox


  • Creamos una nueva página en la carpeta pages de nombre sizedbox_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 (SizedBoxPage) que derive de StatelessWidget (al hacerlo será necesario implementar el método build, ya os da un aviso el Android Studio).



  • Este Widget permite crear un contenedor vacío con un tamaño determinado.
Puede ser utilizado para 'separar' widgets unos de otros.
Ya vimos en el caso de las Listas que podíamos definir un Widget para separar los elementos de la misma. Normalmente poníamos una línea divisoria, pero ahora con este Widget podemos separarlos con espacios en blanco.


La diferencia entre SizedBox y SizedBox.expand es que el segundo establece un ancho y alto igual al ancho y alto disponible estableciendo un valor de double.infinity.
Entre los parámetros que podemos emplear está child (es opcional). Es un Widget que tendrá como tamaño el tamaño indicado en su SizedBox.


  • Veamos un ejemplo:
Flutter dart sizedbox 1.JPG
import 'package:flutter/material.dart';

class SizedBoxPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Ejemplos de SizedBox'),
        ),
        body: _contenido()
    );
  }
  Widget _contenido(){

    return Row(
      children: [
        Expanded(child: _listaElementos(),flex: 1,),
        Expanded(child: _listaSizedBox(),flex: 2,),
      ],

    );

  }

  Widget _listaSizedBox(){   // Ocupa el 66% del ancho => mirar parámetro flex

    return Column(
      children: [
        SizedBox(
          width: 50.0,
          height: 100.0,
          child: Text('Texto dentro de un sizedbox',style: TextStyle(backgroundColor: Colors.blue),),
        ),
        SizedBox(   // Para separar uno de otro
          height: 50.0,
        ),
        SizedBox(
          width: 60.0,
          height: 200.0,
          child: Container(
              child: Text('Texto dentro de un sizedbox con un tamaño más grande',style: TextStyle(backgroundColor: Colors.blue),),
            color: Colors.pink,
          ),
        ),
      ],
    );

  }


  Widget _listaElementos(){

    return Container(
      color: Colors.yellow,
      child: ListView(
        children: [
          Text('Ejemplo de texto de Elemento 1',style: TextStyle(backgroundColor: Colors.green),),
          SizedBox(height: 50.0, ),
          Text('Ejemplo de texto de Elemento 2'),
          SizedBox(height: 50.0, ),
          Text('Ejemplo de texto de Elemento 3'),
        ],
      ),
    );

  }
}



Otros Widgets de diseño


Flex


  • Este Widget tiene el mismo efecto que Row/Column, con la salvedad que podéis establecer la dirección del eje principal (MainAxis) con el parámetro direction el cual puede tener los valores Axis.horizontal / Axis.vertical indicando la dirección de su MainAxis.
Por lo tanto sólo debería usarse cuando queráis a través del valor de alguna variable, cambiar la dirección del eje principal.



Padding


  • Permite establecer un padding sobre un widget indicado en el parámetro child.
El argumento que no puede ser nulo es el padding que debe ser una objeto de una clase que implemente la clase EdgeInsetsGeometry. Normalmente se usa la clase EdgeInsets.
El widget a visualizar puede ser nulo (argumento child) por lo que sólamente visualizaríamos un espacio (el padding establecido).



Stack


  • Permite 'colocar' widgets uno encima de otro, produciendo un solape.



Positioned


  • Asociado al Widget Stack tenemos este widget con sus respectivos constructores que nos permite indicar la 'posición' del widget child indicado dentro del Stack.



OverflowBar

  • Permite tener un desiño horizontal (como un row) de Widget´s y en caso de que no quepan (porque rotamos el dispositivo o por la resolución del mismo) pasará a tener un diseño vertical (como un colum).
Ejemplo de uso: https://medium.com/flutter-community/flutter-responsive-design-size-doesnt-always-matter-6cd88b5e6f2c




SafeArea


  • Permite evitar que el espacio ocupado por partes del dispositivo físico interfiera en la visualización del contenido (como esquinas redondeadas, cámara superior,...)
El scaffold con AppBar ya se encarga de que no interfiera, pero lo normal es envolver el body con este Widget.
Podemos especificar que partes de la pantalla queremos que sean 'protegidas' y que no interfieran con el contenido.



SingleChildScrollView


  • Permite tener un scroll sobre un único Widget (propiedad child).
Este widget debería ser empleado cuando tenemos un conjunto de Widget en el diseño de una pantalla que podrían salirse, al aumentar de tamaño, del tamaño permitido y al no tener un scroll, daría un error.
A diferencia del ListView, este control no debería emplearse cuando se tiene un conjunto de 'items' que queremos que se carguen en forma de lista.



Debugger Diseño


  • Cuando visualizamos un Widget cuyo tamaño excede el espacio disponible veréis que aparece esto en pantalla:
Flutter dart debugger 1.JPG



  • En este vídeo voy a explicar como podemos hacer uso de la herramienta INSPECTOR que forma parte del conjunto de herramientas DEVTOOLS.





Enlaces de interés






Enlace a la página principal de la UD3

Enlace a la página principal del curso




-- Ángel D. Fernández González -- (2021).