Saltar al contenido

FutureBuilder: Aplicación asíncrona con Flutter en Español

noviembre 12, 2020

Aprender a usar FutureBuilder en Flutter es indispensable para poder usar aplicaciones asíncronas y modernas. El uso de FutureBuilder además nos muestra una forma de trabajo típica de Flutter con la que debes familiarizarte.

Cuando realizamos aplicaciones móviles con cualquier lenguaje de programación, casi siempre necesitaremos hacer peticiones que no son contestadas inmediatamente. Hay peticiones, según la optimización que hagamos, que pueden llevar hasta varias segundos. Bueno, necesitamos una funcionalidad que nos permita controlar esto.

Para hacer esto en Flutter usamos los Future y para mostrarlo en pantalla usamos los FutureBuilder. Básicamente lo que hace el Future es detener el flujo normal de la aplicación y esperar a algo para solo después continuar con la ejecución normal. Es un concepto un poco extraño de entender al principio pero aquí lo veremos con algunos ejemplos que lo explican.

Como funciona un Future en Flutter

Un Future es una clase en Flutter que puede contener un tipo de objeto. No tiene sentido usar un Future sin un tipo de objeto específico. Por ejemplo, hagamos la comparación con un suceso de la vida real. Imagina que tu tarea es llenar un balde y llevarlo a casa, vamos a razonar la forma de hacerlo usando un Future.

Otra cosa a tener en cuenta es que lleva un tiempo llenar el balde, tiene que dejarlo un tiempo bajo el grifo para que se llene poco a poco con el chorro de agua. Mientras tanto esperas… Bueno, esto lo representarías de la siguiente manera.

Future<Agua> _llenarBalde() async {
  Agua balde = await _chorroDeAgua();
  return balde;
}

En el código anterior podemos ver que, usamos un Future y entre signos de mayor y menor que tenemos la palabra Agua, esta no es una palabra reservada de Flutter, es un supuesto para favorecer el ejemplo, imagina que es un tipo de datos.

Luego nombramos la función que se llamara _llenarBalde( ) la cual es una función asíncrona por eso usamos la palabra reservada async que hace que la función acepte espera de datos. Esto es necesario y es una de las cosas que suelen olvidarse al principio. Pon atención en ella.

Luego, ya dentro de la función creamos un objeto del tipo que la función solicita Future<Agua>, le ponemos un nombre balde, y usamos la palabra reservada await que hará que nuestro programa espera el resultado de la función que le sigue, en este caso _chorroDeAgua( ). El valor se asignará a la variable balde hasta que la función _chorroDeAgua( ) haya terminado su tarea.

Y para terminar, devolvemos la variable ya con el valor lleno. Si no usáramos el await sería como pasar el balde bajo el chorro sin que se llenara y luego llevarlo a casa de nuevo vacío.

Para mostrarlo en pantalla usamos el FutureBuilder

Con el código anterior únicamente tenemos la información en una variable, pero que aun no la estamos viendo en ningún lugar. Para mostrarla usamos un widget que lee los Future y nos permite tratar la información. Lo hacemos con el siguiente código:

Container(
   child: FutureBuilder<Agua>(
      future: _llenarBalde(),
      builder: (context, snapshot) {
         if (snapshot.hasData) {
            return Text(snapshot.data["litros"]);
         } else if (snapshot.hasError) {
            return Text("${snapshot.error}");
         }

         // By default, show a loading spinner.
         return CircularProgressIndicator();
      },
    ),
),

El FutureBuilder nos pide el Future en su propiedad future. Y en la propiedad builder nos pide una función, la función nos pide el contexto de la aplicación y nos pide una variable cualquiera, la cual será quien recibirá el valor que devuelve el Future. Es decir, recibiría el valor de balde.

Dentro de la función revisamos si el snapshot recibió información con la propiedad .hasData y si tiene información entonces imprimimos la cantidad de litros que tiene (por ejemplo). Si devuelve un error pues representamos el error.

La función tiene un return por defecto el cual se mostrará mientras se llena el balde. En este caso estamos usando un CircularProgressIndicator( ) pero tu podrías mostrar lo que quieras, puede ser un gif creado por ti mismo o cualquier diseño que se te ocurra.

¿Cuando usaremos este tipo los Future en Flutter?

Siempre que hagamos una petición que lleve algún tiempo en resolverse necesitaremos usar programación asíncrona. Por ejemplo, cuando solicitamos información a una API en internet, Cuando cargamos un archivo desde internet o desde el dispositivo.

Son muchos los lugares donde usaremos esta funcionalidad, podemos decir que es prácticamente imposible aprender temas avanzados de Flutter sin entender este concepto. Este artículo es únicamente para darte un ejemplo teórico del funcionamiento de los Future.

Puedes ver un ejemplo de uso en este artículo que hice hace unos días:

Espero que te haya gustado este artículo y especialmente espero que te haya servido, que hayas aprendido algo y que puedas implementarlo en tus próximos proyectos. Un abrazo y hasta la próxima.