Nelle scorse lezioni abbiamo preso familiarità e confidenza con i principali componenti offerti da Flutter per creare un'interfaccia utente e abbiamo analizzato i principi del Material Design e i pattern per UI, come il navigation drawer.
Una qualsiasi applicazione moderna, però, si compone di molteplici schermate che permettono all'utente di interagire con tutte le caratteristiche e funzionalità dell'app. Ad esempio, da un listato di elementi presentato tramite una ListView
, l'utente può selezionare un singolo elemento per visualizzarne i dettagli in una schermata dedicata.
Per fare ciò è importante, dal lato sviluppo, immaginare come l'utente potrebbe muoversi tra le varie schermate in base alle azioni che può compiere, e definire quindi la navigazione in modo che risulti semplice e intuitiva.
Per rendere i contenuti navigabili dall'utente, Flutter mette a disposizione i seguenti tre componenti:
Classe | Descrizione |
---|---|
Route |
è un componente che rappresenta astrattamente una schermata |
Navigator |
è un widget che gestisce le Route mantenendole in uno stack FIFO di widget. La nuova rotta visitata dall'utente è la prima ad essere inserita nello stack e la prima ad uscire nel momento in cui l'utente vuole ritornare alla pagina precedente |
MaterialPageRoute |
rappresenta una rotta modale che sostituisce la schermata corrente con una nuova schermata attraverso la definizione di una transizione relativa alla piattaforma mobile di destinazione |
In questa e nella prossime lezioni andremo a familiarizzare con questi componenti e apprenderemo come condividere i dati tra due schermate tramite appositi esempi pratici e approcci diversi.
Le classi Route, Navigator e MaterialPageRoute
Vediamo quindi le proprietà e i metodi principali che caratterizzano i widget Route
, Navigator
e MaterialPageRoute
.
Iniziamo proprio dal widget Route
, le cui proprietà sono indispensabili per rappresentare astrattamente una schermata dell'applicazione e per la gestione da parte del Navigator
.
Proprietà | Tipo Accettato | Descrizione |
---|---|---|
currentResult |
T |
quando la rotta viene tolta dallo stack del Navigator , se il risultato non è specificato o è nullo, viene utilizzato il valore definito per questa proprietà |
isActive |
bool |
definisce se la rotta è presente nello stack di navigazione. Qualora questa proprietà sia impostata a true e sia anche la schermata corrente, allora la proprietà isCurrent sarà impostata anch'essa a true . Inoltre, se è anche la prima rotta, la proprietà isFirst sarà impostata a sua volta a true |
isCurrent |
bool |
definisce se la rotta è l'ultima entrata nello stack di navigazione, ossia se è la schermata che l'utente sta visualizzando |
isFirst |
bool |
definisce se la rotta è la prima nello stack di navigazione, ossia la schermata più vecchia che l'utente ha navigato. Se così fosse, il metodo Navigator.canPop restituirà false impedendo la rimozione di questa schermata dallo stack di navigazione |
navigator |
NavigatorState |
è lo stato del Navigator in cui si trova la rotta, se presente |
popped |
Future |
quando la rotta viene rimossa dallo stack di navigazione viene completata una Future . Una Future è un oggetto che rappresenta un valore potenziale o un errore che può essere disponibile ad un certo punto del futuro, ossia una computazione posticipata |
settings |
RouteSettings |
rappresenta le impostazioni per la rotta. Queste impostazioni sono definite tramite l'oggetto RouteSettings che gestisce informazioni come il nome e gli argomenti da passare a questa rotta |
Queste proprietà sono indispensabili per comprendere come le Route
vengano gestite dal Navigator
widget.
Il Navigator
widget è infatti il componente che permette la navigazione, in quanto gestisce un set di widget Route
tramite una struttura con stack FIFO, dove la rotta in cima allo stack è la pagina corrente e quelle sotto rappresentano lo storico della navigazione, che permette all'utente di tornare alle pagine precedentemente visualizzate.
Proprietà | Tipo Accettato | Descrizione |
---|---|---|
initialRoute |
String |
rappresenta il nome della prima rotta da mostrare all'utente. Se la stringa contiene qualsiasi carattere / , allora la stringa verrà suddivisa in sotto-stringhe da utilizzare come rotte |
onGenerateRoute |
RouteFactory |
è utilizzata per generare una rotta a partire da un RouteSettings |
onUnknownRoute |
RouteFactory |
in caso di fallimento della callback definita per la proprietà onGenerateRoute , viene utilizzata questa proprietà per gestire l'errore |
Durante lo sviluppo, ci troveremo ad utilizzare spesso i metodi messi a disposizione da questo componente. In particolare, ai fini di questa lezione, ci concentreremo sui principali metodi statici per integrare la navigazione, lasciando la possibilità di esplorare in autonomia gli altri metodi offerti per la gestione delle rotte.
Metodo | Descrizione |
---|---|
pop |
rimuove dallo stack di navigazione l'ultima rotta entrata che è attiva e risulta essere quella corrente |
push |
inserisce nello stack di navigazione una nuova rotta |
pushNamed |
inserisce nello stack di navigazione una nuova rotta sulla base del nome fornito |
Infine, parliamo della classe MaterialPageRoute
.
Questa classe è utilizzata per creare delle nuove rotte modali che vengono mostrate all'utente a seguito di un'animazione. Per fare ciò MaterialPageRoute
estende la classe PageRoute
e definisce delle transizioni che simulano quelle di default definite per Android e iOS.
Vediamo brevemente le proprietà offerte dal widget MaterialPageRoute
.
Proprietà | Tipo Accettato | Descrizione |
---|---|---|
builder |
WidgetBuilder |
permette di creare il contenuto della rotta, ossia il widget che conterrà i dati della pagina |
debugLevel |
String |
rappresenta una breve descrizione della rotta utile per il debugging |
maintainState |
bool |
attraverso questo valore booleano è possibile definire se la rotta deve restare in memoria quando inattiva, ossia quando non è la prima schermata dello stack di navigazione |
transitionDuration |
Duration |
definisce quanto tempo deve durare la transizione tra due schermate |
In particolare, di grande utilità nella definizione delle rotte modali è proprio il costruttore della classe MaterialPageRoute
, che permette di definire attraverso la proprietà builder
il contenuto della rotta modale.
Per ulteriori informazioni sulle proprietà e i metodi non discussi in questa sezione, si rimanda alla documentazione ufficiale di questi tre componenti.