DEV Community

Cover image for Flutter'da Y├Ânlendirme (Routing) ­čĺź ­čîî ÔťĘ
G├╝lsen Keskin
G├╝lsen Keskin

Posted on • Updated on

Flutter'da Y├Ânlendirme (Routing) ­čĺź ­čîî ÔťĘ

Flutter'da Y├Ânlendirme
Flutter'da sayfalar yaln─▒zca rota(route)'lara atad─▒─č─▒m─▒z widget'lard─▒r ve route'lar bir widget olan Navigator taraf─▒ndan y├Ânetilir.

Not: Flutter'da routing(y├Ânlendirme) hi├žbir zaman ger├žekten statik de─čildir, ancak t├╝m rotalar─▒n─▒z─▒ ├Ânceden bildirebilirsiniz.

Declarative routing and named routes (Bildirime dayal─▒ y├Ânlendirme ve adland─▒r─▒lm─▒┼č route'lar)

Her RouteDefinition'─▒n bir yolu(path) ve bir component'i vard─▒r (bu muhtemelen bir sayfad─▒r). Bu genellikle bir uygulaman─▒n en ├╝st d├╝zeyinde yap─▒l─▒r.

Mobil uygulamalar genellikle onlarca sayfay─▒ destekler ve uygulaman─▒n her yerinde ads─▒z yollar olu┼čturmak yerine, onlar─▒ bir kez tan─▒mlay─▒p ard─▒ndan adlar─▒na g├Âre ba┼čvurmak daha kolay bir yoldur.

Declaring routes

Adland─▒r─▒lm─▒┼č route'lar─▒ kullanman─▒n iki b├Âl├╝m├╝ vard─▒r. Birincisi route'lar─▒ belirlemektir.

return MaterialApp(
  debugShowCheckedModeBanner: false,
  theme: _theme,
  routes: {
    ECommerceRoutes.catalogPage: (context) =>
        PageContainer(pageType: PageType.Catalog),
    ECommerceRoutes.cartPage: (context) =>
        PageContainer(pageType: PageType.Cart),
    ECommerceRoutes.userSettingsPage: (context) =>
        PageContainer(pageType: PageType.Settings),
    ECommerceRoutes.addProductFormPage: (context) =>
        PageContainer(pageType: PageType.AddProductForm),
  },
  navigatorObservers: [routeObserver],
);

class ECommerceRoutes {
  static final catalogPage = '/';
  static final cartPage = '/cart';
  static final userSettingsPage = '/settings';
  static final cartItemDetailPage = '/itemDetail';
  static final addProductFormPage = '/addProduct';
}

Enter fullscreen mode Exit fullscreen mode

Adland─▒r─▒lm─▒┼č rotalarda gezinme:
Adland─▒r─▒lm─▒┼č rotalara gitmek, Navigator.pushNamed methodunu kullanmak kadar kolayd─▒r. pushNamed methodu bir BuildContext ve bir route ad─▒ gerektirir, b├Âylece BuildContext'e eri┼čim olan her yerde kullanabilir.

final value = await Navigator.pushNamed(context, "/cart");

Navigator sayfalar─▒ bir "stack" yap─▒s─▒nda yerle┼čtirir. Stack "last in first out" (son giren ilk ├ž─▒kar ilkesine g├Âre ├žal─▒┼č─▒r). Uygulaman─▒z─▒n home page'ine bak─▒yorsan─▒z ve yeni bir sayfaya giderseniz, o yeni sayfay─▒ stack'in ├╝st├╝ne (ve ana sayfan─▒n en ├╝st├╝ne) itersiniz. Stack'deki en ├╝st ├Â─če, ekranda g├Ârd├╝─č├╝n├╝z ┼čeydir.

Navigator, stack benzeri bir yap─▒d─▒r.
Image description

Navigator s─▒n─▒f─▒, stack'i y├Ânetmek i├žin bir dizi yararl─▒ y├Ânteme sahiptir.

ÔÇó pop
ÔÇó popUntil
ÔÇó canPop
ÔÇó push
ÔÇó pushNamed
ÔÇó popAndPushNamed
ÔÇó replace
ÔÇó pushAndRemoveUntil

Adland─▒r─▒lm─▒┼č route'lar─▒ pushlamak'la ilgili ├Ânemli bir not, bir Future d├Ând├╝rmeleridir. await anahtar s├Âzc├╝─č├╝ asenkron(e┼č zamans─▒z) bir de─čer d├Ând├╝ren ifadeleri i┼čaretlemek i├žin kullan─▒l─▒r.

onPressed: () {
    return Navigator.of(context).pushNamed("/cartPage");
},
Enter fullscreen mode Exit fullscreen mode

Not: Navigator.of(context).pushNamed(String routeName) fonksiyon imzas─▒n─▒n, daha ├Ânce bahsedilen Navigator.pushNamed(BuildContext context, String routeName) imzas─▒yla ayn─▒ olmad─▒─č─▒n─▒ fark edebilirsiniz. Bunlar de─či┼čtirilebilir.

MaterialDrawer widget'─▒ ve full men├╝
Bir Materyal Design uygulamas─▒ g├Ârd├╝yseniz, muhtemelen a┼ča─č─▒daki resim de g├Âsterilen app drawer t├╝r├╝n├╝ biliyorsunuzdur.

Image description

─░lk ├Ânce, men├╝n├╝n ger├žekte ne yapmas─▒n─▒ istedi─čimizi d├╝┼č├╝nelim:

  1. Bir kullan─▒c─▒ bir men├╝ d├╝─čmesine dokundu─čunda men├╝ g├Âr├╝nt├╝lenmelidir.

  2. Dokunarak bir route'a giden her sayfa i├žin bir men├╝ item olmal─▒d─▒r.

  3. Uygulama bilgilerini i├žeren bir modal g├Âsteren bir About men├╝ item olmal─▒d─▒r.

  4. Kullan─▒c─▒ bilgilerini g├Âsteren bir men├╝ ba┼čl─▒─č─▒ olmal─▒d─▒r. Kullan─▒c─▒ ayarlar─▒na dokundu─čunuzda, user settings sayfas─▒na y├Ânlendirilmelidir.

  5. Men├╝, o anda hangi route'─▒n aktif oldu─čunu vurgulamal─▒d─▒r.

  6. Bir men├╝ item se├žildi─činde veya bir kullan─▒c─▒ men├╝n├╝n sa─č─▒ndaki men├╝ katman─▒na dokundu─čunda men├╝ kapanmal─▒d─▒r.

  7. Men├╝ a├ž─▒ld─▒─č─▒nda veya kapat─▒ld─▒─č─▒nda, g├╝zel bir ┼čekilde i├žeri ve d─▒┼čar─▒ hareket etmelidir.

Bu ├Âzel men├╝ drawer, t├╝m├╝ Flutter'da yerle┼čik olarak bulunan yaln─▒zca be┼č gerekli widget'─▒n birle┼čimidir:

ÔÇó Drawer
ÔÇó ListView
ÔÇó UserAccountsDrawerHeader
ÔÇó ListTile
ÔÇó AboutListTile

Drawer, bu men├╝y├╝ bar─▒nd─▒ran widget't─▒r. Alt arg├╝man─▒nda tek bir widget al─▒r. Bir Drawer , b├╝y├╝k olas─▒l─▒kla drawer arguman─▒nda bir Scaffold'a iletilecektir.

Ayr─▒ca drawer'l─▒ bir scaffold'da bir AppBar'─▒n─▒z varsa, Flutter app bar'da sa─č tarafta bulunan simgeyi otomatik olarak bir men├╝ butonuna ayarlar ve dokunuldu─čunda men├╝y├╝ a├žar. Men├╝ g├╝zel bir ┼čekilde canland─▒r─▒lacak ve sola kayd─▒rd─▒─č─▒n─▒zda veya sa─čdaki butona dokundu─čunuzda kapanacakt─▒r.

Men├╝ ├Â─čeleri ve uygun widget'lar: ListView ve ListItems

Not: Scaffold'un .automaticallyImplyLeading ├Â─česini false olarak ayarlayarak otomatik men├╝ butonunu ge├žersiz k─▒labilirsiniz.

ListView, widget'lar─▒ kayd─▒r─▒labilir bir container'da d├╝zenleyen bir layout widget'─▒d─▒r. ├çocuklar─▒n─▒ varsay─▒lan olarak dikey(vertically) olarak d├╝zenler, ancak olduk├ža ├Âzelle┼čtirilebilirdir. Child ad─▒nda bir arg├╝man bekleyen di─čer genelle┼čtirilmi┼č widget'lar─▒n aksine, ListTile title, subtitle ve leading (sat─▒r ba┼č─▒) gibi ├Âzelliklere sahiptir ve ayr─▒ca bir onTap ├Âzelli─či ile donat─▒lm─▒┼čt─▒r.

Image description

Bir ListView'i daha "materyal-vari" bir men├╝ drawer'a d├Ân├╝┼čt├╝rmek i├žin ├Âzel olarak kullan─▒lan ba┼čka baz─▒ ├Âzel Flutter widget'lar─▒ da vard─▒r.

├ľrnek AppMenu widget'─▒ olu┼čturma methodu:

@override
  Widget build(BuildContext context) {
    _activeRoute ??= "/";
    return Drawer(
      child: ListView(
        children: <Widget>[
          StreamBuilder( //bir child beklemek yerine builder modelini izler
            // ...
            builder: (
              BuildContext context,
              AsyncSnapshot<ECommerceUser>
            ) => UserAccountsDrawerHeader(),
          ), // StreamBuilder
          ListTile(
            leading: Icon(Icons.apps),
            title: Text("Catalog"),
            selected: _activeRoute == ECommerceRoutes.catalogPage,
            onTap: () => _navigate(ECommerceRoutes.catalogPage),
          ),
          ListTile(...),
          ListTile(...),
          AboutListTile(...),
        ],
      ),
    );
  }

Enter fullscreen mode Exit fullscreen mode

UserAccountsDrawerHeader, ├Ânemli kullan─▒c─▒ bilgilerini g├Âr├╝nt├╝lemek i├žin kullan─▒lan bir Material widget'─▒d─▒r. Butona dokunarak kullan─▒c─▒ hesaplar─▒ aras─▒nda ge├ži┼č yapman─▒z─▒ sa─člayan GMail gibi bir Google uygulamas─▒ hayal edin. Bu GMail benzeri kullan─▒c─▒ aray├╝z├╝n├╝, UserAccountsDrawerHeader kullanarak elde edebilirsiniz.

AboutListTile widget'─▒ ListView.children listesine aktar─▒labilir ve bu a┼ča─č─▒daki listede g├Âsterildi─či gibi yaln─▒zca birka├ž sat─▒r kodla yap─▒land─▒r─▒labilir.

AboutListTile(
  icon: Icon(Icons.info),
  applicationName: "Produce Store",
  aboutBoxChildren: <Widget>[
    Text("Thanks for reading Flutter in Action!"),
  ],
),
Enter fullscreen mode Exit fullscreen mode

Image description

Navigator.pushReplacementNamed

Navigator.pushReplacementNamed, rota y─▒─č─▒n─▒n─▒n yeni sayfalar eklemeye devam etmemesini sa─člar.

Yeni rotan─▒n animasyonu bitti─činde, navigasyon yapt─▒─č─▒n─▒z rotay─▒ kald─▒r─▒r.

─░leti┼čim kutular─▒ veya popup men├╝ler gibi rotalar, kullan─▒c─▒ taraf─▒ndan se├žilen de─čeri rotas─▒n─▒ olu┼čturan widget'a d├Ând├╝rmek i├žin genellikle bu mekanizmay─▒ kullan─▒r.

void _switchToBrightness() {
  Navigator.pushReplacementNamed(context, '/settings/brightness');
}
Enter fullscreen mode Exit fullscreen mode

NavigatorObserver: RouteAware ile aktif rotay─▒ vurgulama

Navigator observer, onu dinleyen herhangi bir widget'a "Hey, e─čer ilgileniyorsan─▒z, Navigator bir olay ger├žekle┼čtiriyor" diyen bir nesnedir.

RouteObserver ise NavigatorObserver'─▒n bir alt s─▒n─▒f─▒d─▒r.
Bu observer(g├Âzlemci), aktif route de─či┼čirse t├╝m dinleyicilerini bilgilendirir.

final RouteObserver<Route> routeObserver =
    RouteObserver<Route>();

class ECommerceApp extends StatefulWidget {
  @override
  _ECommerceAppState createState() => _ECommerceAppState();
}

Enter fullscreen mode Exit fullscreen mode

Route observer'lar─▒n─▒ MaterialApp widget'─▒na iletin:

return MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: _theme,
    home: PageContainer(pageType: PageType.Catalog,),
    routes: { ... }
    navigatorObservers: [routeObserver],
);
Enter fullscreen mode Exit fullscreen mode

Art─▒k observer'─▒ herhangi bir State nesnesinde dinleyebilirsiniz.

State nesnesinin burada g├Âsterildi─či gibi RouteAware ile geni┼čletilmesi gerekir:

class AppMenu extends StatefulWidget {
  @override
  AppMenuState createState() => AppMenuState();
}

class AppMenuState extends State<AppMenu>
    with RouteAware { ... }

Enter fullscreen mode Exit fullscreen mode

RouteAware , bir route observer ile etkile┼čim kurmak i├žin arabirim sa─člayan soyut(abstract) bir s─▒n─▒ft─▒r. Art─▒k state nesnenizin didPop, didPush ve di─čer birka├ž methoda eri┼čimi vard─▒r.

Men├╝y├╝ aktif route ile g├╝ncellemek i├žin stack'de yeni bir sayfa oldu─čunda bilgilendirilmemiz gerekiyor. Bunun iki ad─▒m─▒ vard─▒r: ilk ad─▒m, route observer'dan de─či┼čiklikleri dinlemek, ikinci ad─▒msa, route de─či┼čti─činde haberdar olmak i├žin observer'─▒ dinlemektir.

class AppMenuState extends State<AppMenu> with RouteAware {
  String _activeRoute;
  UserBloc _bloc;

    @override
    void didChangeDependencies() {
        super.didChangeDependencies();
        routeObserver.subscribe(
          this,
          ModalRoute.of(context),
        );
        _bloc = AppStateContainer.of(context)
            .blocProvider.userBloc;
    }
}
Enter fullscreen mode Exit fullscreen mode

Art─▒k bu widget, rota de─či┼čikliklerinin fark─▒nda oldu─čundan, herhangi bir Navigator etkinli─či ger├žekle┼čti─činde aktif rota de─či┼čkenini g├╝ncellemesi gerekir. Bu, RouteAware'den devral─▒nan didPush y├Ânteminde yap─▒l─▒r:

@override
void didPush() {

  _activeRoute =
    ModalRoute.of(context).settings.name;

}

Enter fullscreen mode Exit fullscreen mode

An─▒nda y├Ânlendirme(Routing on the fly)

An─▒nda y├Ânlendirme, bir olaya yan─▒t olarak olu┼čturulana kadar var olmayan bir sayfaya y├Ânlendirme yapabilece─činiz fikridir. ├ľrne─čin, kullan─▒c─▒ bir liste ├Â─česine dokundu─čunda yeni bir sayfaya gitmek isteyebilirsiniz. Bu rotay─▒ ├Ânceden olu┼čturman─▒z gerekmez, ├ž├╝nk├╝ rotalar yaln─▒zca widget'lard─▒r.

void _showListItemDetailPage() async {
    await Navigator.push(//adland─▒r─▒lm─▒┼č route'lara Navigator.pushNamed arac─▒l─▒─č─▒yla gidilir
      context,
      MaterialPageRoute(
        builder: (context) => SettingsPage(
              settings: settings,
            ),
        fullscreenDialog: true, //tam ekran
      ),
    );
  }
Enter fullscreen mode Exit fullscreen mode

Flutter'da, route stack'de yeni bir widget gibi g├Âr├╝nen her ┼čey bir rotad─▒r. Modallar, bottom sheet'ler, snack bar'lar ve diyalog'lar─▒n t├╝m├╝ rotalard─▒r ve bunlar an─▒nda y├Ânlendirme i├žin m├╝kemmel adaylard─▒r.

MaterialRouteBuilder

Future _toProductDetailPage(Product product) async {
    await Navigator.push(//stack'e yeni bir sayfa eklemek i├žin Navigator.push'u kullanabilirsiniz.
        context,
        MaterialPageRoute(//MaterialPageRoute, PageRoute'un bir alt s─▒n─▒f─▒d─▒r ve t├╝m Material widget i┼člevselli─čini widget tree'deki yeni yerinde sa─člar.
            builder: (context) => //MaterialPageRoute gibi route nesneleri, bir callback alan ve widget d├Ând├╝ren bir builder argument de─či┼čkeni gerektirir.
            ProductDetailPageContainer(
              product: product,
            ),
        ),
    );
}\
Enter fullscreen mode Exit fullscreen mode

showSnackBar, showBottomSheet ve benzerleri

Flutter, modallar ve snackbarlar gibi sayfa olmayan route'lar─▒ kullanmay─▒ ├žok kolayla┼čt─▒ran widget'lara ve mant─▒─ča sahiptir. Bunlar bir sayfaya eklenmek yerine Navigator stack'ine eklenen widget'lard─▒r.

Baz─▒ route'lar ekran─▒n tamam─▒n─▒ kaplamaz:
Image description

Bu uygulamada, bottom sheet (iOS uygulamalar─▒nda yayg─▒n olan) ve bir snackbar kullan─▒yoruz. Bunlar, ekran─▒n alt─▒ndan g├Âr├╝nmeleri ve ekran─▒n yaln─▒zca bir b├Âl├╝m├╝n├╝ kaplamalar─▒ bak─▒m─▒ndan benzerdir. Yine de farkl─▒lard─▒r ├ž├╝nk├╝ bottom sheet bir ModalRoute'd─▒r. Yani, g├Âr├╝nt├╝lendi─činde, alt─▒ndaki sayfayla etkile┼čime giremezsiniz. Snack bar, uygulamay─▒ engellemez, bu nedenle g├Âr├╝n├╝mdeyken etkile┼čimde bulunmaya devam edebilirsiniz.

A┼ča─č─▒daki ├Ârnekte bottom sheet ayn─▒ Catalog widget'─▒nda uygulan─▒r ve ProductDetailCard.onLongPress methodu arac─▒l─▒─č─▒yla bir ProductDetailCard'a bas─▒l─▒ tutularak ba┼člat─▒l─▒r:

return ProductDetailCard(
    key: ValueKey(_product.imageTitle.toString()),
    onTap: () => _toProductDetailPage(_product),
    onLongPress: () =>
        _showQuickAddToCart(_product), //Uzun bir bas─▒┼čta, bottom sheet'i g├Âsterir.
    product: _product,
);

Enter fullscreen mode Exit fullscreen mode

Bottom sheet widget ├Ârne─či:
Image description

_showQuickAddToCart methodu:

void _showQuickAddToCart(BuildContext context, Product product) async {
  CartBloc _cartBloc = AppState.of(context).blocProvider.cartBloc;

  int qty = await showModalBottomSheet<int>(//1

    context: context, //2

    builder: (BuildContext context) { //3
        return AddToCartBottomSheet(
            key: Key(product.id),
        );
    });

    _addToCart(product, qty, _cartBloc);
}
Enter fullscreen mode Exit fullscreen mode

1: showModalBottomSheet, Flutter taraf─▒ndan sa─članan ve sizin i├žin y├Ânlendirmeyle(routing) ilgilenen global bir methoddur. T├╝r bildirimi (), bottom sheet'den ne t├╝r verilerin geri g├Ânderilmesini bekleyebilece─činizi s├Âyler. Bu sat─▒r ayr─▒ca showModalBottomSheet'in d├Ân├╝┼č de─čerine bir de─čer atar. Method bir Future d├Ând├╝rd├╝─č├╝nden, wait anahtar s├Âzc├╝─č├╝n├╝ kullanman─▒z gerekir. Future, temel olarak, "Kullan─▒c─▒ bottom sheet'i kapat─▒r kapatmaz size do─čru de─čeri verece─čim ve do─čru de─čeri alaca─č─▒m" der.

2: T├╝m rotalar─▒n bir BuildContext'e ihtiyac─▒ vard─▒r, b├Âylece Flutter bunlar─▒ a─ča├žta nereye ekleyece─čini bilir.

3: T├╝m rota de─či┼čtirme methodlar─▒, widget d├Ând├╝ren bir callback bekler

Image description

class AddToCartBottomSheet extends StatefulWidget {
  const AddToCartBottomSheet({Key key}) : super(key: key);

  @override
  _AddToCartBottomSheetState createState() => _AddToCartBottomSheetState();
}

class _AddToCartBottomSheetState extends State<AddToCartBottomSheet> {
  int _quantity = 0;
  // ...

  @override
  Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: BoxConstraints(
        minWidth: MediaQuery.of(context).size.width,
        minHeight: MediaQuery.of(context).size.height / 2,
      ),
      child: Column(
        children: <Widget>[
          Padding(
            // ...
            child: Text("Add item to Cart"),
          ),
          Padding(
            // ...
            child: Row(
              children: <Widget>[
                IconButton(...) // decrease qty button
                Text(...) // current quanity
                IconButton(...) // increase qty button
              ],
            ),
          ),
          RaisedButton(
            color: AppColors.primary[500],
            textColor: Colors.white,
            child: Text(
              "Add To Cart".toUpperCase(),
            ),
            onPressed: () =>
              Navigator.of(context).pop(_quantity),
          )
        ],
      ),
    );
}


Enter fullscreen mode Exit fullscreen mode

Y├Ânlendirme animasyonlar─▒

Sayfalar yaln─▒zca widget'lard─▒r, bu nedenle di─čer widget'lar gibi canland─▒r─▒labilirler.
Sayfalar─▒n, platforma g├Âre farkl─▒l─▒k g├Âsteren varsay─▒lan ge├ži┼čleri vard─▒r: iOS style ya da Material style.
T├╝m ge├ži┼čler, biri g├Âr├╝nt├╝lenmekte olan ve biri g├Âr├╝nt├╝den ├ž─▒kmakta olan iki sayfa i├žerir.

Ge├ži┼čler PageRoute taraf─▒ndan veya PageRoute'u geni┼čleten MaterialPageRoute, ModalRoute'u ve TransitionRoute'u geni┼čleten MaterialPageRoute taraf─▒ndan i┼členir. Bu karma┼čan─▒n bir yerinde, di─čer ┼čeylerin yan─▒ s─▒ra arg├╝man olarak iki animasyon alan buildTransitions adl─▒ bir method vard─▒r. Birisi ├ž─▒karken kendisi i├žindir, ikincisi ise onun yerini alan rota ile koordinelidir. MaterialPageRoute zaten ge├ži┼čleri uygular, bu da MaterialPageRoute.buildTransitions'─▒ override edebilece─činiz anlam─▒na gelir.

Bu, animasyonlu bir widget'a sar─▒lm─▒┼č sayfay─▒ basit├že d├Ând├╝rebilece─činiz ve sayfan─▒n buna g├Âre canland─▒raca─č─▒ anlam─▒na gelir.

class FadeInSlideOutRoute<T> extends
    MaterialPageRoute<T> {
  FadeInSlideOutRoute({WidgetBuilder builder, RouteSettings settings})
      : super(builder: builder, settings: settings);

  @override
  Widget buildTransitions(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    if (settings.isInitialRoute) return child;
    if (animation.status == AnimationStatus.reverse) {
      return super.buildTransitions(
        context,
        animation,
        secondaryAnimation,
        child,
      );
    }
    return FadeTransition(
        opacity: animation,
        child: child,
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

├ľzet:

ÔÇó Flutter, y├Ânlendirmeyi ├žok daha esnek ve ak─▒c─▒ hale getiren dinamik y├Ânlendirme (routing) kullan─▒r.

ÔÇó Flutter's Navigator, t─▒pk─▒ baz─▒ kullan─▒c─▒ etkile┼čimleri ger├žekle┼čirken veya uygulama yeni veriler al─▒rken, kodunuzda "an─▒nda" rotalar olu┼čturman─▒za olanak tan─▒r.

ÔÇó Navigator, baz─▒ kullan─▒c─▒ etkile┼čimleri ger├žekle┼čirken veya uygulama yeni veriler al─▒rken, kodunuzda "an─▒nda" (on the fly) rotalar olu┼čturman─▒za olanak tan─▒r.

ÔÇó Flutter, adland─▒r─▒lm─▒┼č route'lar─▒ kullanarak statik y├Ânlendirmeyi destekler.

ÔÇó Navigator, t├╝m rotalar─▒ y─▒─č─▒n(stack) ┼čeklinde y├Ânetir.

ÔÇó Rotalara y├Ânlendirme i┼či, Navigator.push ve Navigator.pop methodlar─▒ ├ža─čr─▒larak yap─▒l─▒r.

ÔÇó Navigator.push ├ža─čr─▒lar─▒, yeni rota taraf─▒ndan geri aktar─▒lacak bir de─čeri bekleyen bir Future d├Ând├╝r├╝r.

ÔÇó Flutter'da Material-style menu drawer'─▒ olu┼čturmak birka├ž widget gerektirir: Drawer, ListView, ListTile, AboutListTile ve DrawerHeader.

ÔÇó Bir RouteObserver kurarak ve herhangi bir widget'─▒n state nesnesine abone olarak y├Ânlendirmedeki de─či┼čiklikleri tahmin edebilirsiniz.

ÔÇó Birka├ž UI ├Â─česi Navigator ile y├Ânetilir ve teknik olarak rotalard─▒r, ancak bunlar snackbarlar, alt sayfalar, ├žekmeceler ve men├╝ler gibi sayfalar de─čildir.

ÔÇó GestureDetector widget'─▒n─▒ kullanarak kullan─▒c─▒ etkile┼čimlerini dinleyebilirsiniz.

ÔÇó ├ľzel sayfa ge├ži┼člerini uygulamak, Route s─▒n─▒flar─▒n─▒ extend ederek yap─▒l─▒r.

Resources:
ÔÇóFlutter in Action Chapter: 7
ÔÇóhttps://api.flutter.dev/flutter/widgets/Navigator/pushReplacementNamed.html
ÔÇóhttps://api.flutter.dev/flutter/widgets/RouteObserver-class.html

Top comments (0)