diegoRodicio

View Categories

🧩 Callbacks en Flutter

🔔 Callbacks: executar funcións cando ocorre algo

En Dart xa aprendemos que podemos pasar funcións como parámetros. En Flutter utilizamos esta característica para indicar que acción debe realizarse cando ocorre algo, por exemplo, cando prememos un botón.

Estas funcións chámanse callbacks. En lugar de executalas inmediatamente, entregámolas a un widget para que as execute cando corresponda.

Por exemplo, un botón utiliza a propiedade onPressed para indicar que función debe executarse cando o usuario o preme.

Cando creamos os nosos propios widgets, tamén podemos utilizar callbacks para indicarlles que acción deben realizar.

⚙️ Como se define un callback?

Do mesmo xeito que podemos crear atributos para recibir textos ou números, tamén podemos crear atributos de tipo función.

Por exemplo:

final VoidCallback onTap;

Neste caso, onTap é un atributo que permite indicar que función queremos executar cando se produza unha acción.

Existen diferentes tipos de callbacks segundo os parámetros que reciben:

TipoQue recibe?Que devolve?
VoidCallback (equivale a void Function())Nada.Nada.
void Function(int)Un número enteiro.Nada.
void Function(String)Un texto.Nada.

💡 Lembra: Se non necesitamos enviar ningún valor, podemos utilizar VoidCallback. Se necesitamos enviar información, podemos utilizar void Function(Tipo), indicando o tipo de dato que recibirá a función.

⚡ Callback sen parámetros

Imos crear un widget propio chamado BotonSimple que podemos reutilizar para mostrar diferentes botóns.

Este widget permite indicar:

  • texto: o texto que aparecerá no botón.
  • onTap: a función que se executará cando premamos o botón.

No exemplo, ao premer Saudar, aparecerá a mensaxe «Ola, Diego!» na consola.

🔗 DartPad:

Executar un saúdo mediante un callback sen parámetros
Executar un saúdo mediante un callback sen parámetros

Como funciona?

  1. PantallaSaudo crea un BotonSimple e indícalle o texto e a función que debe executar.
  2. BotonSimple recibe esa función mediante onTap.
  3. Cando prememos o botón, execútase a función recibida.

Fíxate especialmente nesta declaración:

final VoidCallback onTap;

Con ela indicamos que BotonSimple terá unha propiedade chamada onTap na que podemos gardar unha función sen parámetros.

Despois, no construtor, utilizamos required this.onTap para indicar que debemos proporcionar esa función ao crear o widget.

Finalmente, asignámola á propiedade onPressed do botón:

onPressed: onTap

Deste xeito, podemos reutilizar o mesmo botón para realizar diferentes accións, sen modificar o seu código.

📤 Callback cun parámetro

No exemplo anterior, o botón executaba unha función sen parámetros.

Agora imos crear un botón que, ademais de executar unha función, lle indique á pantalla cantos puntos debe sumar.

Para iso:

  • PantallaPuntos: garda os puntos e encárgase de actualizalos.
  • BotonPuntos: mostra un botón e comunica cantos puntos queremos sumar.

Crearemos dous botóns: un que suma 1 punto e outro que suma 5 puntos.

Neste caso, o callback debe recibir un número enteiro, polo que o declaramos así:

final void Function(int) onSumar;

Esta declaración indica que onSumar é unha función que recibe un número enteiro (int) e non devolve ningún resultado (void).

🔗 DartPad:

Enviar a cantidade de puntos ao pai mediante un callback
Enviar a cantidade de puntos ao pai mediante un callback

Que sucede cando prememos «Sumar 5»?

  1. O botón executa onSumar(5).
  2. A función _sumar da pantalla recibe o número 5.
  3. Mediante setState(), aumentamos os puntos e actualizamos a pantalla.

Fíxate en que os dous botóns utilizan a mesma función _sumar, pero cada un envía unha cantidade diferente:

BotonPuntos(cantidade: 1, onSumar: _sumar),
BotonPuntos(cantidade: 5, onSumar: _sumar),

Así, o botón non necesita saber como se gardan os puntos nin como se actualiza a pantalla. Simplemente comunica a cantidade que queremos sumar.

🕓 Pasar unha función ou executala?

Nos exemplos anteriores aparecen diferentes formas de utilizar callbacks:

ExpresiónQue fai?
onPressed: _incrementarEntrega a función para executala cando se prema.
onSumar: _sumarEntrega unha función que recibirá un enteiro cando o fillo a chame.
onPressed: () => onSumar(cantidade)Entrega unha función sen parámetros que, ao premer, chama a outra cun argumento.

É importante comprender a diferenza entre pasar unha función e executala.

Por exemplo:

onPressed: _incrementar

Estamos indicando que función queremos executar máis adiante, cando premamos o botón.

En cambio:

onPressed: _incrementar()

Estamos executando a función inmediatamente, mentres se constrúe o botón. Ademais, neste exemplo produciríase un erro porque _incrementar() devolve void, en lugar dunha función.

📥 E se necesitamos enviar un argumento?

Cando queremos executar unha función que necesita un argumento, podemos utilizar unha función anónima, é dicir, unha función sen nome.

Por exemplo:

onPressed: () => onSumar(cantidade)

Neste caso:

  1. () => crea unha función anónima sen parámetros.
  2. Cando prememos o botón, execútase esa función.
  3. A función chama a onSumar(cantidade), enviando o número correspondente.

Deste xeito, conseguimos que onSumar(cantidade) non se execute ao crear o botón, senón cando o usuario o prema.

💡 Lembra: Para executar unha función máis adiante, pasámola sen chamala. Se necesitamos enviar argumentos, podemos utilizar unha función anónima, como () => onSumar(cantidade).


📚 Consulta: