Perché Rive?
Quando si parla di animazioni vettoriali in Flutter, il pensiero corre subito a Lottie. Tuttavia esiste un'alternativa sempre più matura: Rive. Rive non è solo un formato, ma un intero editor che permette di creare animazioni vettoriali, definire una State Machine e controllarla direttamente dal codice Flutter.
I vantaggi principali rispetto a Lottie sono:
- File leggeri: i
.rivsono spesso più compatti dei JSON di Lottie. - Interattività reale: grazie alla State Machine puoi reagire a input dell'utente senza ricaricare l'animazione.
- Runtime ottimizzato: il rendering avviene tramite il motore Rive, pensato per le performance.
- Controllo da codice: puoi modificare variabili (inputs) e far cambiare stato all'animazione in tempo reale.
Installazione
Aggiungi il pacchetto al tuo pubspec.yaml:
dependencies:
rive: ^0.13.1
Poi inserisci il file .riv (esportato dall'editor su rive.app) nella cartella assets e dichiaralo:
flutter:
assets:
- assets/animations/hero.riv
Visualizzare una semplice animazione
Il widget più immediato è RiveAnimation.asset, che carica e riproduce un'animazione:
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class SimpleRive extends StatelessWidget {
const SimpleRive({super.key});
@override
Widget build(BuildContext context) {
return const SizedBox(
height: 250,
child: RiveAnimation.asset(
'assets/animations/hero.riv',
fit: BoxFit.contain,
),
);
}
}
Di default viene riprodotta la prima animazione presente nel file. Puoi specificarne una particolare con il parametro animations.
Controllare la State Machine
Il vero punto di forza di Rive è la State Machine. Per interagire con essa occorre ottenere i suoi SMIInput. Vediamo un esempio con un input booleano che cambia stato al tocco:
class InteractiveRive extends StatefulWidget {
const InteractiveRive({super.key});
@override
State<InteractiveRive> createState() => _InteractiveRiveState();
}
class _InteractiveRiveState extends State<InteractiveRive> {
StateMachineController? _controller;
SMIBool? _isPressed;
void _onRiveInit(Artboard artboard) {
final controller = StateMachineController.fromArtboard(
artboard,
'State Machine 1',
);
if (controller != null) {
artboard.addController(controller);
_controller = controller;
_isPressed = controller.findInput<bool>('pressed') as SMIBool?;
}
}
void _toggle() {
_isPressed?.value = !(_isPressed?.value ?? false);
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _toggle,
child: SizedBox(
height: 200,
child: RiveAnimation.asset(
'assets/animations/button.riv',
stateMachines: const ['State Machine 1'],
onInit: _onRiveInit,
),
),
);
}
}
Tipi di input disponibili
Rive mette a disposizione tre tipi di input controllabili da codice:
- SMIBool: stato on/off (es. toggle, hover).
- SMINumber: valore numerico (es. percentuale di completamento).
- SMITrigger: impulso istantaneo che scatena una transizione (es. click di conferma).
Esempio con un trigger:
final trigger = controller.findInput<bool>('success') as SMITrigger?;
// In risposta a un evento:
trigger?.fire();
Rive Events: ascoltare gli eventi
Dalle versioni recenti, Rive supporta gli eventi emessi dall'animazione stessa, utili per sincronizzare la logica dell'app con momenti precisi dell'animazione:
controller.addEventListener((event) {
if (event.name == 'animationComplete') {
// naviga o aggiorna lo stato
}
});
Rive vs Lottie: quando scegliere cosa
| Aspetto | Rive | Lottie |
|---|---|---|
| Interattività | Nativa (State Machine) | Limitata |
| Peso file | Generalmente minore | Maggiore |
| Ecosistema designer | Editor proprietario | After Effects + Bodymovin |
| Controllo runtime | Molto granulare | Principalmente playback |
Se la tua animazione è puramente decorativa e prodotta da un motion designer in After Effects, Lottie resta una scelta valida. Se invece hai bisogno di interattività o di controllo fine da codice (bottoni animati, onboarding interattivi, mascotte reattive), Rive offre un vantaggio concreto.
Buone pratiche
- Rilascia sempre il controller nel metodo
disposeper evitare memory leak. - Verifica i nomi di State Machine e input: devono corrispondere esattamente a quelli definiti nell'editor.
- Evita troppe State Machine attive contemporaneamente su schermo per non gravare sul rendering.
- Usa
BoxFitappropriato per evitare deformazioni dell'artboard.
Conclusione
Rive porta in Flutter animazioni vettoriali leggere e soprattutto interattive, colmando il limite principale di Lottie. Grazie alle State Machine e agli eventi, puoi costruire interfacce vive che reagiscono all'utente con poche righe di codice. Per progetti che puntano su micro-interazioni curate, vale sicuramente la pena di sperimentarlo.
