Route — je abstraktní třída ve Flutter, která představuje samostatnou obrazovku nebo stránku v historii navigace Navigator. Konkrétní implementace Route — MaterialPageRoute, CupertinoPageRoute a PlatformRoute — určují, jak se obrazovka zobrazuje a jaká animace se používá při přechodu. Na rozdíl od běžného widgetu má Route vlastní životní cyklus s metodami didPush, didPop, didReplace a didChangeNext. Podle Flutter API Reference (2026) každý Route spravuje ModalBarrier, zohledňuje platformní specifika (posun zpět na iOS) a zajišťuje izolaci stavu mezi obrazovkami.
Hlavní body
Route — je základ navigačního systému Flutter. Každou obrazovku, kterou uživatel vidí v aplikaci, představuje objekt Route umístěný v zásobníku Navigator. Route abstrahuje obrazovku od řídícího kódu: Navigator přidává a odebírá Route a uvnitř Route se nachází rozhraní, které uživatel vidí. Taková architektura odděluje odpovědnost mezi navigací a zobrazením.
Na rozdíl od jednoduché výměny widgetů poskytuje Route služby nedostupné běžným widgetům: ModalBarrier (ztmavení pozadí při otevřeném dialogu), správu animace vstupu a výstupu, zpracování hardwarového tlačítka „Zpět“ na Androidu a integraci s Hero animací pro plynulé přechody mezi obrazovkami.
Podle Flutter Cookbook (2026) je Route klíčovým prvkem pro Hero animaci: widget Hero na jednom Route automaticky animuje přechod k widgetu Hero na dalším Route a vytváří efekt „letícího“ prvku. To je možné právě proto, že Route uchovává obě obrazovky v Overlay během animace.
Route je základem jak pro jednoduché mobilní aplikace (přes Navigator 1.0), tak pro složité scénáře s hlubokými odkazy (Navigator 2.0). V Navigator 2.0 Route představuje Page, který RouterDelegate převádí z konfigurace trasy. Porozumění Route je tedy nezbytné pro práci s jakýmkoli navigačním systémem Flutter — bez ohledu na zvolený přístup nebo balíček.
Flutter poskytuje několik vestavěných implementací Route, z nichž každá přizpůsobuje chování konkrétní platformě. Výběr správného typu Route ovlivňuje uživatelský zážitek: Material animace na Androidu a Cupertino animace na iOS vytvářejí pocit „nativní“ aplikace.
| Typ Route | Animace | Platforma | Vlastnosti |
|---|---|---|---|
| MaterialPageRoute | Posun zdola nahoru | Android, desktop | stín při přechodu, automatické zpracování SafeArea |
| CupertinoPageRoute | Posun zprava doleva | iOS, iPadOS | gesto posunu zpět, průhledné pozadí při přechodu |
| PlatformRoute | Automatický výběr | Všechny platformy | vybírá typ na základě TargetPlatform |
| PageRouteBuilder | Vlastní | Všechny platformy | plná kontrola nad animací přes AnimationController |
MaterialPageRoute — nejčastěji používaná implementace Route. Animuje vstup nové obrazovky zdola nahoru s postupným zobrazováním. Při výstupu se obrazovka animuje shora dolů a vrací se do výchozí pozice. Panel nástrojů (AppBar) a tělo obrazovky se animují odděleně, což vytváří efekt hierarchie.
CupertinoPageRoute napodobuje UINavigationController z iOS. Nová obrazovka vstupuje zprava a zakrývá předchozí. Klíčová vlastnost — podpora interaktivního gesta posunu zpět, implementovaná přes CupertinoBackGestureDetector. Toto gesto je zpracováváno i uprostřed animace, což poskytuje přirozené chování známé uživatelům iPhone.
Route má vlastní životní cyklus, který se liší od životního cyklu běžného StatefulWidget. Porozumění tomuto cyklu je nezbytné pro správnou inicializaci dat, přihlášení k odběru streamů a uvolnění zdrojů při zavírání obrazovky.
Životní cyklus Route se skládá ze čtyř hlavních fází. Transition — Route je vytvořen a animován při vstupu (volá se didPush). Active — Route je plně zobrazen a interaguje s uživatelem. Inactive — jiný Route zakrývá aktuální (dialog, spodní obrazovka), ale Route zůstává v zásobníku. Disposed — Route je odstraněn ze zásobníku a zničen, volají se didPop a dispose.
Metody životního cyklu Route lze přepsat ve vlastní implementaci. Například didPop se volá, když je Route odstraněn ze zásobníku — zde lze uložit koncept dat. didChangeNext se volá, když se další Route v zásobníku změnil — užitečné pro aktualizaci UI při změně historie navigace.
Podle Flutter API Route.didPop (2026) je důležité nezaměňovat životní cyklus Route s životním cyklem State uvnitř Route. StatefulWidget uvnitř Route má vlastní initState a dispose, které se volají ve fázích Transition a Disposed. Route žije déle než jeho interní State — Route zůstává v Overlay, i když jsou jeho widgety dočasně skryty jiným Route.
Route poskytuje mechanismy pro přenos dat jak na vstupu (při vytvoření), tak na výstupu (při dokončení). Správný přenos dat přes Route eliminuje potřebu globálních proměnných a InheritedWidget, čímž činí navigaci typově bezpečnou a předvídatelnou.
Pro přenos dat na novou obrazovku se používá konstruktor přijímajícího widgetu nebo argument arguments v Navigator.pushNamed. Uvnitř Route jsou data přístupná přes RouteSettings.arguments, který je uložen v objektu Route. Tento přístup funguje pro všechny typy Route — MaterialPageRoute, CupertinoPageRoute a vlastní implementace.
Pro vrácení dat se používá druhý argument Navigator.pop(context, result). Navigator.push vrací Future
Při přímém volání Navigator.push s MaterialPageRoute jsou data přenášena přes konstruktor cílové obrazovky. MethodChannel se nepoužívá — je to čistá Dart interakce. Tento přístup je preferován pro typově bezpečný přenos složitých objektů.
Podívejme se na příklad vytvoření vlastního Route s vlastní animací a přenosem dat. PageRouteBuilder umožňuje definovat animaci vstupu a výstupu s plnou kontrolou nad křivkou animace a dobou trvání.
// Vlastní Route s animací posunu
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),
));
// Vrátit data z obrazovky
ElevatedButton(
onPressed: () => Navigator.of(context).pop({'selected': true, 'id': '42'}),
child: const Text('Vybrat'),
);
// Získat výsledek na volající obrazovce
final result = await Navigator.push(context, MaterialPageRoute(
builder: (context) => const SelectionPage(),
));
if (result != null) {
print('Vybráno: ${result['selected']}');
}
V příkladu PageRouteBuilder definuje vlastní animaci posunu zdola s průhledností. transitionDuration nastavuje rychlost animace. Kód také demonstruje předávání výsledku: detailní obrazovka vrací Map s výběrem uživatele a volající obrazovka získává tato data přes Future z push. Route zajišťuje úplnou izolaci: koncepty na detailní obrazovce neovlivňují stav seznamu.
Často kladené otázky
Route — je objekt, který spravuje obrazovku na úrovni navigace: ukládá animaci, ModalBarrier a životní cyklus. Widget — je popis části rozhraní. Route obsahuje Widget uvnitř sebe, ale také poskytuje služby (vrstva Overlay, Hero animace) nedostupné běžným widgetům. Jeden Route může obsahovat složitou hierarchii widgetů libovolné hloubky.
Použijte PageRouteBuilder s parametry pageBuilder (stavba obrazovky) a transitionsBuilder (definice animace). V transitionsBuilder jsou k dispozici animation (0.0–1.0) a secondaryAnimation pro paralelní animace. Pro úplnou kontrolu vytvořte podtřídu Route a přepište buildPage, createAnimationController a buildTransitions, což poskytne přístup k nízkoúrovňovým AnimationController.
Pro přenos složitých objektů použijte konstruktor cílové obrazovky při přímém Navigator.push nebo argument arguments při pushNamed. Ujistěte se, že objekt je serializovatelný (Map, JSON nebo vlastní třída). Pro typově bezpečný přenos ve Flutter se používají modely freezed nebo json_serializable, které zaručují správnou deserializaci při přenosu přes RouteSettings.
Route.dispose se nevolá, pokud Route zůstává v zásobníku Navigator. Například při otevření nového Route přejde starý Route do neaktivního stavu (Inactive), ale není zničen — zůstává v zásobníku pro rychlý návrat. Dispose se volá pouze při odstranění Route ze zásobníku pomocí pop, pushReplacement nebo pushAndRemoveUntil. Pro uvolnění zdrojů použijte dispose State uvnitř Route, nikoli dispose samotného Route.
Použijte ModalRoute.of(context) k získání aktuálního Route z BuildContext. Vlastnost ModalRoute.isActive ukazuje, zda je Route aktuálně viditelná obrazovka. ModalRoute.isCurrent — true, pokud je Route na vrcholu zásobníku. Pro sledování změn v zásobníku se přihlaste k odběru pozorovatelů Navigator přes RouteAware a RouteObserver, kteří upozorňují na změnu aktivního Route.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také