🔔 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:
| Tipo | Que 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 utilizarvoid 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:

Como funciona?
PantallaSaudocrea unBotonSimplee indícalle o texto e a función que debe executar.BotonSimplerecibe esa función medianteonTap.- 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:

Que sucede cando prememos «Sumar 5»?
- O botón executa
onSumar(5). - A función
_sumarda pantalla recibe o número5. - 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ón | Que fai? |
|---|---|
onPressed: _incrementar | Entrega a función para executala cando se prema. |
onSumar: _sumar | Entrega 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:
() =>crea unha función anónima sen parámetros.- Cando prememos o botón, execútase esa función.
- 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: