Route — cos'è, tipi e creazione di route in Flutter

Autore: IT Sectr Pubblicato: 2026-07-02 Tempo di lettura: 8 min

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 — una classe astratta di schermata in Flutter con un proprio ciclo di vita (didPush, didPop, didReplace, didChangeNext)
  • MaterialPageRoute — l'implementazione standard di Route con animazione Material (scorrimento dal basso) per Android e desktop
  • CupertinoPageRoute — implementazione di Route con animazione iOS (scorrimento da destra + gesto di swipe indietro) per iPhone e iPad
  • Ciclo di vita — Route attraversa le fasi: Transizione, Attivo, Inattivo e Smaltito
  • Trasferimento dati — Route accetta argomenti tramite il costruttore e restituisce un risultato tramite Future al completamento

Cos'è Route in Flutter

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 come blocco costitutivo della navigazione

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.

Tipi di Route: MaterialPageRoute e CupertinoPageRoute

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 RouteAnimazionePiattaformaCaratteristiche
MaterialPageRouteScorrimento dal basso verso l'altoAndroid, desktopOmbra durante la transizione, gestione automatica di SafeArea
CupertinoPageRouteScorrimento da destra a sinistraiOS, iPadOSGesto di swipe indietro, sfondo trasparente durante la transizione
PlatformRouteSelezione automaticaTutte le piattaformeSeleziona il tipo in base a TargetPlatform
PageRouteBuilderPersonalizzataTutte le piattaformeControllo totale sull'animazione tramite AnimationController

MaterialPageRoute: standard per Android

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: stile di navigazione iOS

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.

Ciclo di vita di Route: dalla creazione allo smaltimento

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.

Fasi del ciclo di vita di Route

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.

Passaggio di dati tramite Route tra schermate

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, che si completa con il valore passato a pop. Se pop viene chiamato senza argomento, Future si completa con null. Questo meccanismo è analogo a startActivityForResult in Android e al completion handler in iOS, ma implementato tramite Dart Futures.

Passaggio di dati tramite il costruttore di Route

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.

Esempio di creazione di Route personalizzato

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.

dart
// 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

Qual è la differenza tra Route e Widget in Flutter?

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à.

Come creare una Route con animazione personalizzata?

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.

Come passare un oggetto complesso tra Route?

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.

Perché Route potrebbe non chiamare dispose?

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.

Come verificare quale Route è attualmente attiva?

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

  • Route — una classe astratta di schermata in Flutter con ciclo di vita (didPush, didPop, didReplace, didChangeNext) e supporto per ModalBarrier e animazione Hero
  • MaterialPageRoute — implementazione Android con animazione di scorrimento dal basso, ombra e SafeArea automatica
  • CupertinoPageRoute — implementazione iOS con animazione di scorrimento da destra e gesto interattivo di swipe indietro
  • PageRouteBuilder — utilità per creare Route con animazione personalizzata tramite transitionsBuilder e AnimationController
  • Passaggio dati — tramite costruttore di Route (push) o arguments (pushNamed) in input; tramite Navigator.pop(context, result) in output con Future
  • Ciclo di vita — quattro fasi: Transizione (didPush), Attivo, Inattivo (coperto da un'altra Route), Smaltito (didPop + dispose)
  • Isolamento schermate — ogni Route ha il proprio BuildContext e stato, prevenendo perdite e semplificando la gestione dei dati

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.

Discuti il progetto

Leggi anche