Képernyők közötti navigáció egy gyakori jellemzője szinte mindenféle mobilalkalmazásnak. Képernyőre lépés a Navigator.push metódussal lehetséges.
Azt már talán tudjuk, hogy a Navigator osztállyal tudjuk ezt a bizonyos navigációt megtenni. Például a
Navigator.pop(context)
utasítással tudtuk azt megtenni, hogy „bezárjuk” az aktuális képernyőt és visszalépjünk egy előző képernyőre. Tehát a pop metódust használtuk erre a célra.
A push metódust tudjuk arra használni, hogy egy másik képernyőre jussunk:
Navigator.push(context, route)
A push egy context és egy route értéket vár paraméterként.
Navigator alapgondolata
A Flutterben a navigáció stack, azaz verem alapú. Ezt úgy kell elképzelni, hogy a képernyők rétegesen egymás alatt-felett helyezkednek el.
Ebből a felhasználó mindig csak azt látja, ami legfelül van. A push metódus egy réteget „nyom” mindig ebbe a tárolóba legfelülre. A pop metódus pedig a legfelső réteget veszi ki, törli a veremből. Így jutunk vissza a pop-al az aktuális képernyő (felső réteg) előtti képernyőre (második réteg).
push paraméterei: context
A push-nak tehát van két paramétere. A context és a route. A context egy StatelessWidget-ben nem érhető el globálisan.
Tegyük fel, hogy van a StatelessWidget-en belül egy osztály függvény / metódus, amin keresztül a push-t hívjuk:
void _selectCategory() {
Navigator.push(context, route);
}
A függvénynek kell megadni egy BuildContext típusú context-et, amit már tudunk használni a push-on belül:
void _selectCategory(BuildContext context) {
Navigator.push(context, route);
}
A push hívásnak van egy alternatívája is:
Navigator.of(context).push(route);
route
A context már tiszta. Mi a helyzet a route paraméterrel? A route-ot úgy lehet megadni, hogy példányosítjuk a MaterialPageRoute osztályt.
Ha a VSCode-ra bízzuk és hagyjuk, hogy a kódot automatikusan kiegészítse, akkor ezt kapjuk:
Navigator.of(context).push(MaterialPageRoute(builder: builder));
A MaterialPageRoute vár egy builder paramétert, ami egy függvényt vár értékként. Ez a függvény pedig egy context-et vár (ezt automatikusan meg is kapja) és egy Widget-et ad vissza (ez abból látszik, hogy a függvény típusa Widget:
A visszaadott Widget lesz az a képernyő widget, amit meg kell jeleníteni. Példának okáért ez most a mi egyéni MealsScreen nevű widgetünk:
void _selectCategory(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (ctx) => MealsScreen(
title: 'Some title',
meals: [],
),
),
);
}
Példa működése
A példában ez a kiinduló képernyő, ahol kategóriát lehet választani:
Ez pedig egy kiválasztott, alaphelyzetben üres képernyő:
Amit látunk még, az a felső sorban megjelenő balra mutató navigációs nyíl, amire kattintva visszajutunk (pop) az előző képernyőre. Ezt a Flutter automatikusan odabiggyeszti és a nyílhoz sem kellett semmit sem manuálisan kódolnunk.