Route è una classe astratta in Flutter che rappresenta una schermata o pagina separata nella cronologia di navigazione del Navigator. Le implementazioni concrete di Route — MaterialPageRoute, CupertinoPageRoute e PlatformRoute — determinano come viene visualizzata la schermata e quale animazione viene utilizzata durante la transizione. A differenza di un widget normale, Route ha un proprio ciclo di vita con i metodi didPush, didPop, didReplace e didChangeNext. Secondo Flutter API Reference (2026), ogni Route gestisce ModalBarrier, tiene conto delle caratteristiche specifiche della piattaforma (swipe indietro su iOS) e garantisce l'isolamento dello stato tra le schermate.
Punti chiave
Route è il fondamento del sistema di navigazione di Flutter. Ogni schermata che l'utente vede in un'applicazione è rappresentata da un oggetto Route situato nello stack del Navigator. Route astrae la schermata dal codice di controllo: Navigator aggiunge e rimuove Route, mentre all'interno di Route si trova l'interfaccia che l'utente vede. Questa architettura separa la responsabilità tra navigazione e visualizzazione.
A differenza della semplice sostituzione di widget, Route fornisce servizi non disponibili per i widget normali: ModalBarrier (oscuramento dello sfondo quando un dialogo è aperto), controllo dell'animazione di entrata e uscita, gestione del pulsante fisico Indietro su Android e integrazione con l'animazione Hero per transizioni fluide tra schermate.
Secondo Flutter Cookbook (2026), Route è un elemento chiave per l'animazione Hero: un widget Hero su una Route anima automaticamente la transizione verso un widget Hero sulla Route successiva, creando un effetto di elemento “volante”. Questo è possibile proprio perché Route mantiene entrambe le schermate nell'Overlay durante l'animazione.
Route è la base sia per applicazioni mobili semplici (tramite Navigator 1.0) sia per scenari complessi con collegamenti profondi (Navigator 2.0). In Navigator 2.0, Route rappresenta una Page che RouterDelegate converte dalla configurazione di route. Pertanto, comprendere Route è essenziale per lavorare con qualsiasi sistema di navigazione Flutter — indipendentemente dall'approccio o dal pacchetto scelto.
Flutter fornisce diverse implementazioni integrate di Route, ciascuna adattando il comportamento a una piattaforma specifica. Scegliere il tipo corretto di Route influisce sull'esperienza utente: l'animazione Material su Android e l'animazione Cupertino su iOS creano la sensazione di un'applicazione “nativa”.
| Tipo di Route | Animazione | Piattaforma | Caratteristiche |
|---|---|---|---|
| MaterialPageRoute | Scorrimento dal basso verso l'alto | Android, desktop | Ombra durante la transizione, gestione automatica di SafeArea |
| CupertinoPageRoute | Scorrimento da destra a sinistra | iOS, iPadOS | Gesto di swipe indietro, sfondo trasparente durante la transizione |
| PlatformRoute | Selezione automatica | Tutte le piattaforme | Seleziona il tipo in base a TargetPlatform |
| PageRouteBuilder | Personalizzata | Tutte le piattaforme | Controllo totale sull'animazione tramite AnimationController |
MaterialPageRoute è l'implementazione di Route più utilizzata. Anima la nuova schermata che entra dal basso verso l'alto con apparizione graduale. In uscita, la schermata anima dall'alto verso il basso, tornando alla posizione originale. La barra degli strumenti (AppBar) e il corpo della schermata animano separatamente, creando un effetto di gerarchia.
CupertinoPageRoute imita UINavigationController di iOS. La nuova schermata entra da destra, coprendo la precedente. La caratteristica principale è il supporto per il gesto interattivo di swipe indietro, implementato tramite CupertinoBackGestureDetector. Questo gesto viene gestito anche durante l'animazione, fornendo un comportamento naturale familiare agli utenti iPhone.
Route ha un proprio ciclo di vita, che differisce dal ciclo di vita di un normale StatefulWidget. Comprendere questo ciclo è necessario per la corretta inizializzazione dei dati, le sottoscrizioni agli stream e il rilascio delle risorse alla chiusura di una schermata.
Il ciclo di vita di Route consiste in quattro fasi principali. Transizione — Route viene creata e animata all'ingresso (viene chiamato didPush). Attivo — Route viene visualizzata completamente e interagisce con l'utente. Inattivo — un'altra Route copre quella corrente (dialogo, foglio inferiore), ma la Route rimane nello stack. Smaltito — Route viene rimossa dallo stack e distrutta, vengono chiamati didPop e dispose.
I metodi del ciclo di vita di Route possono essere sovrascritti in un'implementazione personalizzata. Ad esempio, didPop viene chiamato quando Route viene rimossa dallo stack — qui è possibile salvare dati di bozza. didChangeNext viene chiamato quando la Route successiva nello stack è cambiata — utile per aggiornare l'UI quando cambia la cronologia di navigazione.
Secondo Flutter API Route.didPop (2026), è importante non confondere il ciclo di vita di Route con il ciclo di vita di State all'interno di Route. StatefulWidget all'interno di Route ha il proprio initState e dispose, che vengono chiamati rispettivamente durante le fasi di Transizione e Smaltimento. Route vive più a lungo del suo State interno — Route rimane nell'Overlay anche quando i suoi widget sono temporaneamente nascosti da un'altra Route.
Route fornisce meccanismi per passare dati sia in input (alla creazione) che in output (al completamento). Il corretto passaggio di dati tramite Route elimina la necessità di variabili globali e InheritedWidget, rendendo la navigazione type-safe e prevedibile.
Per passare dati a una nuova schermata, utilizzare il costruttore del widget ricevente o il parametro arguments in Navigator.pushNamed. All'interno di Route, i dati sono accessibili tramite RouteSettings.arguments, memorizzati nell'oggetto Route. Questo approccio funziona per tutti i tipi di Route — MaterialPageRoute, CupertinoPageRoute e implementazioni personalizzate.
Per restituire dati, utilizzare il secondo argomento di Navigator.pop(context, result). Navigator.push restituisce Future
Quando si chiama direttamente Navigator.push con MaterialPageRoute, i dati vengono passati tramite il costruttore della schermata di destinazione. MethodChannel non viene utilizzato — questa è un'interazione Dart pura. Questo approccio è preferibile per il passaggio type-safe di oggetti complessi.
Consideriamo un esempio di creazione di un Route personalizzato con una propria animazione e passaggio di dati. PageRouteBuilder consente di definire animazioni di entrata e uscita con controllo totale sulla curva di animazione e sulla durata.
// Route personalizzato con animazione di scorrimento
Navigator.push(context, PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) {
return DetailPage(productId: '42');
},
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 0.3);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return SlideTransition(position: offsetAnimation, child: child);
},
transitionDuration: const Duration(milliseconds: 400),
));
// Restituire dati dalla schermata
ElevatedButton(
onPressed: () => Navigator.of(context).pop({'selected': true, 'id': '42'}),
child: const Text('Seleziona'),
);
// Ottenere il risultato sulla schermata chiamante
final result = await Navigator.push(context, MaterialPageRoute(
builder: (context) => const SelectionPage(),
));
if (result != null) {
print('Selezionato: ${result['selected']}');
}
Nell'esempio, PageRouteBuilder definisce un'animazione personalizzata di scorrimento dal basso con trasparenza. transitionDuration imposta la velocità dell'animazione. Il codice dimostra anche il passaggio del risultato: la schermata di dettaglio restituisce una Map con la selezione dell'utente e la schermata chiamante riceve questi dati tramite Future da push. Route garantisce un completo isolamento: le bozze sulla schermata di dettaglio non influenzano lo stato dell'elenco.
Domande frequenti
Route è un oggetto che gestisce una schermata a livello di navigazione: memorizza animazione, ModalBarrier e ciclo di vita. Widget è una descrizione di una parte dell'interfaccia. Route contiene Widget al suo interno, ma fornisce anche servizi (livello Overlay, animazione Hero) non disponibili per i widget normali. Una Route può contenere una gerarchia complessa di widget di qualsiasi profondità.
Utilizzare PageRouteBuilder con i parametri pageBuilder (costruzione della schermata) e transitionsBuilder (definizione dell'animazione). In transitionsBuilder sono disponibili animation (0.0–1.0) e secondaryAnimation per animazioni parallele. Per il controllo totale, creare una sottoclasse di Route e sovrascrivere buildPage, createAnimationController e buildTransitions, fornendo accesso ad AnimationController di basso livello.
Per passare oggetti complessi, utilizzare il costruttore della schermata di destinazione quando si chiama direttamente Navigator.push o il parametro arguments con pushNamed. Assicurarsi che l'oggetto sia serializzabile (Map, JSON o classe personalizzata). Per il passaggio type-safe in Flutter, utilizzare modelli freezed o json_serializable, che garantiscono una deserializzazione corretta quando passati tramite RouteSettings.
Route.dispose non viene chiamato se Route rimane nello stack del Navigator. Ad esempio, quando si apre una nuova Route, la vecchia Route passa allo stato inattivo ma non viene distrutta — rimane nello stack per un rapido ritorno. Dispose viene chiamato solo quando Route viene rimossa dallo stack tramite pop, pushReplacement o pushAndRemoveUntil. Per rilasciare risorse, utilizzare il dispose di State all'interno di Route, non il dispose della Route stessa.
Utilizzare ModalRoute.of(context) per ottenere la Route corrente da BuildContext. La proprietà ModalRoute.isActive mostra se la Route è la schermata attualmente visibile. ModalRoute.isCurrent — true se la Route è la cima dello stack. Per osservare le modifiche dello stack, sottoscriversi agli osservatori del Navigator tramite RouteAware e RouteObserver, che notificano i cambiamenti della Route attiva.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche