Navigasyon bir ekrandan diğerine gezinmeyi sağlayan yönteme verilen isimdir.
Flutter'da ekranlar arasında gezinmek bir çok seçenek vardır bunlar:
• MaterialPageRoute ile doğrudan gezinme.
• Route Map ile statik navigasyon
• Generated Routes ile dinamik navigasyon
1. MaterialPageRoute ile Doğrudan Gezinme
Navigator'ın bir örneğine erişir ve yeni bir MaterialPageRoute'u içeri gönderirsiniz. Rota, navigasyon yığınının üstünde yeni bir Widget oluşturur.
Navigator.push(context, MaterialPageRoute<void>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('My Page')),
body: Center(
child: TextButton(
child: Text('POP'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
},
));
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => LobbyScreen(),
),
);
MaterialPageRoute
, yönlendirmekten daha fazlasından sorumludur. Geçişi kontrol eder ve istediğiniz zaman geri dönebilmeniz için eski rotayı bellekte tutar. Bir önceki sayfaya geri dönebilmek için de Navigator.pop() yöntemini kullanırız. Bu yöntem, ilk Widget'ı yığından kaldırır.
2. Route Map ile Statik Navigasyon
Provider
veya BloC
pattern gibi bir state yönetimi aracı kullanıyorsanız bu tercih edilen yoldur. Farklı WidgetBuilder methodlarını tanımlayan ve navigasyonla ilgilenen String key'ler ile bir Map oluşturma seçeneğiniz vardır.
void main() {
runApp(MaterialApp(
home: MyAppHome(), // becomes the route named '/'
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => MyPage(title: 'page A'),
'/b': (BuildContext context) => MyPage(title: 'page B'),
'/c': (BuildContext context) => MyPage(title: 'page C'),
},
));
}
Bir rotayı ada göre göstermek için aşağıdaki yöntemi kullanın:
Navigator.pushNamed(context, '/b');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.light(),
initialRoute: LoginScreen.route,
routes: {
LobbyScreen.route: (context) => LobbyScreen(),
LoginScreen.route: (context) => LoginScreen(),
GameScreen.route: (context) => GameScreen(),
},
);
Navigator.pushNamed(context, LobbyScreen.route);
Statik "route", belirli Widget'lara giden yolu tanımlayan string içeren bir değişkendir.
Route'larınızdan biri örneğin eğik çizgi içeriyorsa, en az bir yolu "/" ile sağlamanız gerektiğini unutmayın.
Tek dezavantajı, argüman iletememenizdir.
Argüman iletme dinamik navigasyon tarafında ele alınacaktır.
- onGeneratedRoute ile Dinamik Navigasyon
onGeneratedRoute, rotalar oluşturabilme ve iletilen bağımsız değişkenlere erişebilme avantajına sahiptir.
onGenerateRoute: (settings) {
switch (settings.name) {
case LoginScreen.route:
return MaterialPageRoute(builder: (_) => LoginScreen());
break;
case LobbyScreen.route:
return MaterialPageRoute(builder: (_) => LobbyScreen());
break;
case GameScreen.route:
return MaterialPageRoute(builder: (_) => GameScreen());
break;
default:
return MaterialPageRoute(builder: (_) => LoginScreen());
}
}
arguments parametresi ile yeni rotaya iletmek istediğiniz argümanları gönderebilirsiniz.
Aşağıdaki örneğin işlevi LobbyScreen.route route'una user-msg adında değeri "Thank you for reading!" olan bir argüman iletmektir.
onPressed: () {
Navigator.pushNamed(
context,
LobbyScreen.route,
arguments: {"user-msg": "Thank you for reading!"},
);
}
onGenerateRoute: (settings) {
switch (settings.name) {
case LoginScreen.route:
return MaterialPageRoute(builder: (_) => LoginScreen());
break;
case LobbyScreen.route:
return MaterialPageRoute(builder: (_) =>
LobbyScreen(
settings.arguments
));
break;
case GameScreen.route:
return MaterialPageRoute(builder: (_) => GameScreen());
break;
default:
return MaterialPageRoute(builder: (_) => LoginScreen());
}
},
Gönderdiğimiz argümana ulaşmak için: arguments["user-msg"] biçimini kullanırız.
class LobbyScreen extends StatelessWidget {
static const String route = "lobby-new";
final Map<String, String> arguments;
LobbyScreen(this.arguments);
@override
Widget build(BuildContext context) {
...
Text(
arguments["user-msg"],
style: GoogleFonts.sawarabiGothic(fontSize: 34.0),
textAlign: TextAlign.center,
)
...
}
}
Rotalar bir değer döndürebilir
Aşağıdaki örnekte Tamam'a basıldığında value değişkenine true değeri atanır. Kullanıcı geri düğmesine basarsa value değişkeninin değeri null olur.
Bir ekrandan diğerine değer döndürmek için navigasyon kullanıldığında rotanın type parametresi pop sonucunun türüyle aynı olmalıdır.
bool value = await Navigator.push(context, MaterialPageRoute<bool>(
builder: (BuildContext context) {
return Center(
child: GestureDetector(
child: Text('Tamam'),
onTap: () { Navigator.pop(context, true); }
),
);
}
));
Tür belirtmemeyi tercih ederseniz void kullanabilirsiniz.
MaterialPageRoute<void>MaterialPageRoute
Popup routes:
showDialog , showMenu ve showModalBottomSheet gibi işlevler, itilen rotanın geleceğini (Future) yukarıda açıklandığı gibi döndürür. Arayanlar, rota açıldığında bir işlem yapmak veya rotanın değerini almak için döndürülen değeri bekleyebilir.
PopupMenuButton
ve DropdownButton
gibi açılır pencereler oluşturan widget'lar da vardır. Bu widget'lar, PopupRoute'un
dahili alt sınıflarını oluşturur ve bunları göstermek ve kapatmak için Navigator'ın push ve pop methodlarını kullanır.
Custom routes
PageRouteBuilder sınıfı, geri aramalar açısından özel bir rota tanımlamayı mümkün kılar.
Aşağıda rota göründüğünde veya kaybolduğunda çocuğunu döndüren ve solduran bir örnek görüyorsunuz.Bu rota, opaque: false
olduğu için bir popup route'ın yaptığı gibi tüm ekranı gizlemez.
Navigator.push(context, PageRouteBuilder(
opaque: false,
pageBuilder: (BuildContext context, _, __) {
return Center(child: Text('My PageRoute'));
},
transitionsBuilder: (___, Animation<double> animation, ____, Widget child) {
return FadeTransition(
opacity: animation,
child: RotationTransition(
turns: Tween<double>(begin: 0.5, end: 1.0).animate(animation),
child: child,
),
);
}
));
references:
https://api.flutter.dev/flutter/widgets/Navigator-class.html
https://medium.com/flutter-community/everything-you-need-to-know-about-flutter-navigation-d0c5e549b3c
Top comments (0)