Jonny Borges
Committed by GitHub

Merge pull request #2338 from gizemgizg/master

🇹🇷 Turkish documents of State Management, Route Management and Dependency Management files were create.
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 [![Korean](https://img.shields.io/badge/Language-Korean-blueviolet?style=for-the-badge)](README.ko-kr.md) 34 [![Korean](https://img.shields.io/badge/Language-Korean-blueviolet?style=for-the-badge)](README.ko-kr.md)
35 [![French](https://img.shields.io/badge/Language-French-blueviolet?style=for-the-badge)](README-fr.md) 35 [![French](https://img.shields.io/badge/Language-French-blueviolet?style=for-the-badge)](README-fr.md)
36 [![Japanese](https://img.shields.io/badge/Language-Japanese-blueviolet?style=for-the-badge)](README.ja-JP.md) 36 [![Japanese](https://img.shields.io/badge/Language-Japanese-blueviolet?style=for-the-badge)](README.ja-JP.md)
  37 +[![Turkish](https://img.shields.io/badge/Language-Turkish-blueviolet?style=for-the-badge)](README.tr-TR.md)
37 38
38 39
39 </div> 40 </div>
  1 +![](https://raw.githubusercontent.com/jonataslaw/getx-community/master/get.png)
  2 +
  3 +[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get)
  4 +[![popularity](https://badges.bar/get/popularity)](https://pub.dev/packages/sentry/score)
  5 +[![likes](https://badges.bar/get/likes)](https://pub.dev/packages/get/score)
  6 +[![pub points](https://badges.bar/get/pub%20points)](https://pub.dev/packages/get/score)
  7 +![building](https://github.com/jonataslaw/get/workflows/build/badge.svg)
  8 +[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)
  9 +[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)
  10 +[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx)
  11 +[![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)
  12 +<a href="https://github.com/Solido/awesome-flutter">
  13 +<img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />
  14 +</a>
  15 +<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>
  16 +
  17 +![](https://raw.githubusercontent.com/jonataslaw/getx-community/master/getx.png)
  18 +
  19 +
  20 +<div align="center">
  21 +
  22 +**Languages:**
  23 +
  24 +
  25 +[![English](https://img.shields.io/badge/Language-English-blueviolet?style=for-the-badge)](README.md)
  26 +[![Vietnamese](https://img.shields.io/badge/Language-Vietnamese-blueviolet?style=for-the-badge)](README-vi.md)
  27 +[![Indonesian](https://img.shields.io/badge/Language-Indonesian-blueviolet?style=for-the-badge)](README.id-ID.md)
  28 +[![Urdu](https://img.shields.io/badge/Language-Urdu-blueviolet?style=for-the-badge)](README.ur-PK.md)
  29 +[![Chinese](https://img.shields.io/badge/Language-Chinese-blueviolet?style=for-the-badge)](README.zh-cn.md)
  30 +[![Portuguese](https://img.shields.io/badge/Language-Portuguese-blueviolet?style=for-the-badge)](README.pt-br.md)
  31 +[![Spanish](https://img.shields.io/badge/Language-Spanish-blueviolet?style=for-the-badge)](README-es.md)
  32 +[![Russian](https://img.shields.io/badge/Language-Russian-blueviolet?style=for-the-badge)](README.ru.md)
  33 +[![Polish](https://img.shields.io/badge/Language-Polish-blueviolet?style=for-the-badge)](README.pl.md)
  34 +[![Korean](https://img.shields.io/badge/Language-Korean-blueviolet?style=for-the-badge)](README.ko-kr.md)
  35 +[![French](https://img.shields.io/badge/Language-French-blueviolet?style=for-the-badge)](README-fr.md)
  36 +[![Japanese](https://img.shields.io/badge/Language-Japanese-blueviolet?style=for-the-badge)](README.ja-JP.md)
  37 +[![Turkish](https://img.shields.io/badge/Language-Turkish-blueviolet?style=for-the-badge)](README.tr-TR.md)
  38 +
  39 +</div>
  40 +
  41 +- [Get Hakkında](#get-hakkında)
  42 +- [Kurulum](#kurulum)
  43 +- [GetX ile Sayaç Uygulaması](#getx-ile-sayaç-uygulaması)
  44 +- [Üç Temel Kavram](#üç-temel-kavram)
  45 + - [State Management (Durum Yönetimi)](#state-management-durum-yönetimi)
  46 + - [Reactive State Manager (Reaktif Durum Yönetimi)](#reactive-state-manager-reaktif-durum-yönetimi)
  47 + - [State Management Hakkında Daha Fazla Bilgi](#state-management-hakkında-daha-fazla-bilgi)
  48 + - [Route Management (Rota Yönetimi)](#route-management-rota-yönetimi)
  49 + - [Route Management Hakkında Daha Fazla Bilgi](#route-management-hakkında-daha-fazla-bilgi)
  50 + - [Dependency Management (Bağımlılık Yönetimi)](#dependency-management-bağımlılık-yönetimi)
  51 + - [Dependency Management Hakkında Daha Fazla Bilgi](#dependency-management-hakkında-daha-fazla-bilgi)
  52 +- [Utils](#utils)
  53 + - [Internationalization (Uluslararasılaştırma)](#internationalization-uluslararasılaştırma)
  54 + - [Translations (Çeviriler)](#translations-çeviriler)
  55 + - [Translations Kullanımı](#translations-kullanımı)
  56 + - [Locales (Yerel Ayarlar)](#locales-yerel-ayarlar)
  57 + - [Locale Değiştirme](#locale-değiştirme)
  58 + - [System locale (Yerel Sistem Ayarları)](#system-locale-yerel-sistem-ayarları)
  59 + - [Tema Değiştirme](#tema-değiştirme)
  60 + - [GetConnect](#getconnect)
  61 + - [Varsayılan Ayarlar](#varsayılan-ayarlar)
  62 + - [Özel Ayarlarlamalar](#özel-ayarlamalar)
  63 + - [GetPage Middleware](#getpage-middleware)
  64 + - [Priority (Öncelik)](#priority-öncelik)
  65 + - [Redirect (Yönlendirme)](#redirect-yönlendirme)
  66 + - [onPageCalled](#onpagecalled)
  67 + - [OnBindingsStart](#onbindingsstart)
  68 + - [OnPageBuildStart](#onpagebuildstart)
  69 + - [OnPageBuilt](#onpagebuilt)
  70 + - [OnPageDispose](#onpagedispose)
  71 + - [Advanced APIs (Gelişmiş API'ler)](#advanced-apis-gelişmiş-apiler)
  72 + - [Opsiyonel Genel Ayarlar ve Manuel Ayarlamalar](#opsiyonel-genel-ayarlar-ve-manuel-ayarlamalar)
  73 + - [Local State Widgets (Yerel Durum Widgetları)](#local-state-widgets-yerel-durum-widgetları)
  74 + - [ValueBuilder](#valuebuilder)
  75 + - [ObxValue](#obxvalue)
  76 + - [Faydalı İpuçları](#faydalı-ipuçları)
  77 + - [GetView](#getview)
  78 + - [GetResponsiveView](#getresponsiveview)
  79 + - [Nasıl Kullanılır?](#nasıl-kullanılır)
  80 + - [GetWidget](#getwidget)
  81 + - [GetxService](#getxservice)
  82 +- [2.0 İle Gelen Büyük Değişiklikler](#20-ile-gelen-büyük-değişiklikler)
  83 +- [Neden Getx?](#neden-getx)
  84 +- [Topluluk](#topluluk)
  85 + - [Topluluk Kanalları](#topluluk-kanalları)
  86 + - [Nasıl katkıda bulunulur?](#nasıl-katkıda-bulunulur)
  87 + - [Makaleler ve Videolar](#makaleler-ve-videolar)
  88 +
  89 +# Get Hakkında
  90 +
  91 +- GetX, Flutter için oldukça basit ve güçlü bir çözüm yoludur. Yüksek performanslı state managment (durum yönetimi), yetenekli dependency injection (bağımlılık enjeksiyonu) ve route management'ı (rota yönetimi) hızlı ve pratik şekilde bir araya getirir.
  92 +
  93 +- GetX'in 3 temel ilkesi vardır. Bu ilkeler kütüphanedeki tüm kaynaklar için önemlidir: **ÜRETKENLİK, PERFORMANS VE ORGANİZASYON.**
  94 +
  95 + - **PERFORMANS:** GetX, performansa ve kaynakların minimum düzeyde tüketimine odaklanmıştır. GetX, Streams ya da ChangeNotifier kullanmaz.
  96 +
  97 + - **ÜRETKENLİK:** GetX kolay ve keyifli bir syntax (yazım kuralları) kullanır. Ne yapmak istersen iste GetX'de her zaman kolay bir çözüm yolu vardır. Saatlerce süren geliştirmeden tasarruf etmeyi ve uygulanın size sağladığı performansı maksimum seviyede kullanmayı mümkün kılar.
  98 +
  99 + Normalde geliştirici, controller'ları hafızadan kaldırmakla ilgilenmelidir. GetX ile bunu yapmaya gerek kalmaz çünkü varsayılan olarak kaynaklar kullanılmadığı zaman hafızadan kendiliğinden kaldırılır. Eğer hafızada tutmak istiyorsanız, dependency içinde "permanent: true" olarak tanımlanmanız gerekmektedir. Bu şekilde hem zaman tasarrufu hem de hafızadaki gereksiz dependency'lerin oluşturabileceği riskler azaltmış olur. Dependency yüklemesi varsayılan olarak lazy'dir (tembeldir).
  100 +
  101 + - **ORGANİZASYON:** GetX, presentation logic'i (sunum mantığını, business logic'i (iş mantığını), dependency injection'ı, navigasyonu View'dan tamamen ayırmayı sağlar. Route'lar arasında navigasyon için context'e gerek duyulmaz bu sayede widget tree'ye (widget ağacına) bağımlı kalmazsınız. Controllers ya da blocs'daki inheritedWidget'a erişmek için context'e ihtiyaç duyulmaz böylelikle presentation logic ve business logic, view katmanından tamamen ayrılır. Controllers/Models/Blocs sınıflarını widget tree'ye inject (aktarırken) ederken `MultiProvider`'lar kullanılmasına ihtiyaç yoktur. GetX'in kendine ait dependency injection özelliği sayesinde DI'yi de view'dan tamamen ayrır.
  102 +
  103 + GetX ile varsayılan olarak temiz kod kullanılarak uygulamadaki her bir özelliğin nerede bulunduğuna ulaşabilirsiniz. Bakım kolaylığının yanı sıra Flutter'da düşünüleyemeyen bir şey olan modülleri paylaşmayı tamamen mümkün kılar.
  104 + BLoC, Flutter'daki kodları organize etmenin başlangıç noktasıdır. Business logic'i, view'dan ayırır. Bunun gelişmiş hali olarak ortaya çıkan GetX sadece business logic'i ayırmakla kalmayıp aynı zamanda dependency injection'ları, route'ları ve presentation logic'i de view'dan ayırır. Data layer (Veri katmanı) bu sayede bütün katmanların dışında bırakılır. Her şeyin nerde olduğunu bilmek "hello word" oluşturmaktan çok daha kolay bir yoldur.
  105 + GetX, Flutter SDK'sı ile çok kolay, pratik ve ölçeklenebilir yüksek performanslı uygulamalar yapmanızı sağlar. Birlikte çalışılabilen büyük bir ekosistem içerir. Yeni başlayanlar için oldukça kolay ve uzmanlar için de doğru olandır. Güvenli, stabil, güncel ve Flutter SDK'da varsayılan olarak olmayan büyük kapsamlı APIs kullanabilmeyi sağlar.
  106 +
  107 +- GetX şişkin değildir. Çoklu davranış içeren özellikleri kullanarak, herhangi bir endişe olmaksızın programlamaya başlamanızı sağlar. Ancak bu özellikler farklı taraflarda olup sadece kullanıldıktan sonra başlatılır. Sadece state management kullanıyorsanız, sadece bu derlenir. Sadece routes kullanırsanız, state management'dan hiçbir şey derlenmez.
  108 +
  109 +- GetX büyük bir ekosistemdir. Geniş bir topluluk, çok sayıda destekçi içerir ve Flutter var olduğu sürece bu korunacaktır. GetX, tek bir kod ile Android, iOS, Web, Mac, Linux, Windows veya kendi server'ınız (sunucunuz) üzerinde çalışmaya elverişlidir.
  110 + **[Get Server](https://github.com/jonataslaw/get_server) ile frontend üzerinde yaptığınız kodu backend üzerinde tamamen yeniden kullanmanız mümkün**.
  111 +
  112 +**Ek olarak, tüm geliştirme süreci hem server'da hem de frontend'de [Get CLI](https://github.com/jonataslaw/get_cli) ile tamamen otomatikleştirilebilir**.
  113 +
  114 +**Ayrıca üretkenliğinizi arttırmak için
  115 +[VSCode eklentileri](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) ve the [Android Studio/Intellij eklentileri](https://plugins.jetbrains.com/plugin/14975-getx-snippets) vardır.**
  116 +
  117 +# Kurulum
  118 +
  119 +pubspec.yaml dosyasına Get’i ekleyin:
  120 +
  121 +```yaml
  122 +dependencies:
  123 + get:
  124 +```
  125 +
  126 +Get’i kullanılacak sayfaya import ediyoruz:
  127 +
  128 +```dart
  129 +import 'package:get/get.dart';
  130 +```
  131 +
  132 +# GetX ile Sayaç Uygulaması
  133 +
  134 +“Sayaç” projesi yeni bir Flutter projesi oluştururken varsayılan olarak gelir. Yorum satırları ile birlikte toplam 100 satır içerir. Get’in gücünü göstermek gerekirse, size bir “sayaç” uygulamasının her bir tıklamada durumunu değiştirip, sayfalar arasında hareket edip ve bunu yaparken state'leri (durumları) aktarıp aynı zamanda organize bir yol izleyerek business logic'i view'dan ayıracağız ve bu YORUM SATIRLARI DAHİL SADECE 26 SATIR İÇERECEK.
  135 +
  136 +- 1.Adım:
  137 + “Get”’i MaterialApp’den önce GetMaterialApp'e dönüştürerek ekliyoruz.
  138 +
  139 +```dart
  140 +void main() => runApp(GetMaterialApp(home: Home()));
  141 +```
  142 +
  143 +- Not: Bu kullanım Flutter’ın sağladığı MaterialApp’i modifiye etmez. Sadece child'ı (çocuğu) MaterialApp olan ve bir öncesinde konfigüre edilmiş bir widget’tır. Kendiniz de manuel olarak konfigüre edebilirsiniz fakat buna gerek yoktur. GetMaterialApp, route’ları oluşturacak ve içine bunları, translation’ları ve route navigation için ihtiyacınız olabilecek olan her şeyi inject edecektir. Eğer Get’i sadece state management ya da dependency management olarak kullanmak isterseniz, GetMaterialApp kullanmanıza gerek yoktur. Bu yapı routes, snackbars, internationalization, bottomSheets, dialogs, ve route'lara bağlı high-level apis kullanımlarında ek olarak da context'in yokluğundaki durumlarda kullanılmalıdır.
  144 +- Not²: Bu adım sadece route management kullanıldığında gereklidir (`Get.to()`, `Get.back()` ve bunlar gibi). Kullanmayacaksanız 1. adımı yapmanıza gerek yoktur.
  145 +
  146 +- 2.Adım:
  147 + İş mantıklarını içeren sınıfı oluşturup içine tüm değişkenleri metodları ve controller'ları ekleyin.İstediğiniz herhangi bir değişkeni ".obs" ile gözlemlenebilir yapabilirsiniz.
  148 +
  149 +```dart
  150 +class Controller extends GetxController{
  151 + var count = 0.obs;
  152 + increment() => count++;
  153 +}
  154 +```
  155 +
  156 +- 3.Adım:
  157 + View'ı oluşturun ve içine StatelessWidget (bu RAM'den tasarruf sağlar) yerleştirin. Get sayesinde StatefulWidget kullanmanıza gerek yoktur.
  158 +
  159 +```dart
  160 +class Home extends StatelessWidget {
  161 +
  162 + @override
  163 + Widget build(context) {
  164 +
  165 + // Sınıfınızın nesnesini getirmek için Get.put() kullanılır. Bu içindeki tüm "child" route'ları görüntülenebilir yapar.
  166 + final Controller c = Get.put(Controller());
  167 +
  168 + return Scaffold(
  169 + // Sayaç her değiştiğinde Text() içindeki değerin güncellenmesi için Obx(()=> kullanılır
  170 + appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
  171 +
  172 + // Navigator.push içeren 8 satırı basit bir şekilde Get.to() ile değiştirin. Bunda context'e ihtiyacınız kalmamaktadır.
  173 + body: Center(child: ElevatedButton(
  174 + child: Text("Go to Other"), onPressed: () => Get.to(Other()))),
  175 + floatingActionButton:
  176 + FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
  177 + }
  178 +}
  179 +
  180 +class Other extends StatelessWidget {
  181 + // Önceki sayfada zaten kulllandığımız Controller'ı, Get'de "find" diyerek getirmesinini istiyoruz.
  182 + final Controller c = Get.find();
  183 +
  184 + @override
  185 + Widget build(context){
  186 + // Güncellenen sayaç değişkenine erişiyoruz.
  187 + return Scaffold(body: Center(child: Text("${c.count}")));
  188 + }
  189 +}
  190 +```
  191 +
  192 +Sonuç:
  193 +
  194 +![](https://raw.githubusercontent.com/jonataslaw/getx-community/master/counter-app-gif.gif)
  195 +
  196 +Bu basit bir proje ama Get'in ne kadar güçlü olduğunu zaten açıkça ortaya koyuyor. Projeniz büyüdükçe bu gücü daha iyi anlacaksınız.
  197 +
  198 +Get, ekiplerle çalışmak üzere tasarlanmıştır. Ayrıca bireysel geliştiricinin de işini oldukça kolaylaştırır.
  199 +
  200 +Performanstan ödün vermeden her şeyi zamanında teslim etmenize yardımcı olur. Get tam olarak sana layık!
  201 +
  202 +# Üç Temel Kavram
  203 +
  204 +## State management (Durum Yönetimi)
  205 +
  206 +Get iki farklı state manager içerir: simple state manager (GetBuilder da denilir) ve reactive state manager (GetX/Obx)
  207 +
  208 +### Reactive State Manager (Reaktif Durum Yönetimi)
  209 +
  210 +Reaktif programlama, birçok kişi tarafından karmaşık olduğu söylendiği için kafa karışıklığına yol açabilir. Ancak GetX, reaktif programlamayı oldukça basit bir hale dönüştürür:
  211 +
  212 +- StreamController'ları oluşturmanıza ihtiyacınız yoktur.
  213 +- Her bir değişken için StreamBuilder oluşturmanıza gerekmez.
  214 +- Her state için sınıf oluşturmanıza gerek yoktur.
  215 +- Başlangıç değerleri için get metodu oluşturmaya ihtiyaç olmaz.
  216 +- Code generators kullanmanız gerekmez.
  217 +
  218 +Get, reaktif programlamayı setState kullanmak kadar kolay yapmaktadır.
  219 +
  220 +Bir isim değişkeniniz olduğunu ve onu her değiştirdiğinizde, onu kullanan tüm widget'ların otomatik olarak güncellendiğini düşünün.
  221 +
  222 +Bu sizin sayaç değişkeniniz:
  223 +
  224 +```dart
  225 +var name = 'Jonatas Borges';
  226 +```
  227 +
  228 +Gözlemlenebilir yapmak için ".obs" ekliyorsunuz ve bu şekli alıyor:
  229 +
  230 +```dart
  231 +var name = 'Jonatas Borges'.obs;
  232 +```
  233 +
  234 +UI'da (kullanıcı arayüzünde) bu değeri göstermek ve değerler değiştiğinde ekranı güncellemek istediğinizde, hemen şunu yapın:
  235 +
  236 +```dart
  237 +Obx(() => Text("${controller.name}"));
  238 +```
  239 +
  240 +Hepsi bu. İşte _bu kadar_ basit.
  241 +
  242 +### State Management Hakkında Daha Fazla Bilgi
  243 +
  244 +**State Management'ın daha ayrıntılı bir açıklamasına [buradan](./documentation/en_US/state_management.md) erişebilirsiniz. Orada daha fazla örnek ile simple state manager ve reactive state manager arasındaki farkı görebilirsiniz**
  245 +
  246 +GetX'in gücü hakkında daha iyi bir fikir edineceksiniz.
  247 +
  248 +## Route Management (Rota Yönetimi)
  249 +
  250 +Eğer routes/snackbars/dialogs/bottomsheets yapılarını context'e ihtiyaç duymadan kullanmak istedğinizde, GetX bunun için biçilmiş kaftan.
  251 +
  252 +MaterialApp'i GetMaterialApp ile değiştiriyoruz.
  253 +
  254 +```dart
  255 +GetMaterialApp( // Önceki hal: MaterialApp(
  256 + home: MyHome(),
  257 +)
  258 +```
  259 +
  260 +Yeni ekrana geçmek için:
  261 +
  262 +```dart
  263 +
  264 +Get.to(NextScreen());
  265 +```
  266 +
  267 +Name (isim) ile yeni sayfaya geçiş yapılabilir. Named routes (İsimli rotalar) hakkında daha çok bilgiye [buradan](./documentation/tr_TR/route_management.md#navigation-with-named-routes) ulaşabilirsiniz.
  268 +
  269 +```dart
  270 +
  271 +Get.toNamed('/details');
  272 +```
  273 +
  274 +Snackbars, dialogs, bottomsheets ve normalde Navigator.pop(context) ile kapatacağınız herhangi bir şeyi kapatmak için;
  275 +
  276 +```dart
  277 +Get.back();
  278 +```
  279 +
  280 +Önceki ekrana geri dönme seçeneğinin olmadan bir sonraki ekrana gitmek için (örnek olarak SplashScreens, login screens, vs.)
  281 +
  282 +```dart
  283 +Get.off(NextScreen());
  284 +```
  285 +
  286 +Sonraki ekrana gitmek ve önceki tüm route'ları kapatmak için shopping carts, polls, ve test'lerde kullanılır)
  287 +
  288 +```dart
  289 +Get.offAll(NextScreen());
  290 +```
  291 +
  292 +Bunlardan herhangi birini yapmak için context kullanmanız gerekmediğini fark ettiniz mi? Get route management'ı kullanmanın en büyük avantajlarından biri de budur. Böylelikle controller sınıfınızda olan tüm metodları endişe olmadan çalıştırabilirsiniz.
  293 +
  294 +### Route Management Hakkında Daha Fazla Bilgi
  295 +
  296 +**Get, named routes ile çalışırken route'lar arası geçişleri kolayca kontrol etmenizi sağlar. Daha ayrıntılı doküman için [buraya](./documentation/tr_TR/route_management.md) tıklayabilirsiniz.**
  297 +
  298 +## Dependency Management (Bağımlılık Yönetimi)
  299 +
  300 +Get basit ve güçlü bir dependency manager içerir. Sadece tek satır kod ile Bloc ya da Controller'ınızın aynı sınıf nesnesini getirmenizi sağlar. Ayrıca Provider context, ya da inheritedWidget kullanmanıza gerek kalmaz:
  301 +
  302 +```dart
  303 +Controller controller = Get.put(Controller()); // Controller controller = Controller(); yazmak yerine
  304 +```
  305 +
  306 +- Not: Get'in State Manager'ını kullanıyorsanız, API bağlamaya daha çok dikkat edin ki onlar view'ı controller'a kolayca bağlamanızı sağlayacaktır.
  307 +
  308 +Kullanacağınız sınıfın içinde başka bir sınıfın nesnesini oluşturmak yerine, Get instance sayesinde uygulamanızın her yerinde aynı sınıf nesnesini kullanabilir hale getirebilirsiniz.
  309 +Böylelikle controller (ya da Bloc sınıfını) normal bir şekilde kullanabilirsiniz.
  310 +
  311 +**İpucu:** Get dependency management, kütüphanenin diğer parçalarından ayrıdır. Örnek olarak eğer uygulamanızda hali hazırda state manager kullanıyorsanız (hangisi olduğu fark etmez), en baştan yazmaya gerek yoktur. Bu dependency injection'ı problem olmadan kullanabilirsiniz.
  312 +
  313 +```dart
  314 +controller.fetchApi();
  315 +```
  316 +
  317 +Farzedin ki çok fazla sayıda route'larınız ve controller'larınızda erişmeniz gereken data'lar olsun, state manager'ı Provider ya da Get_it gibi kütüphaneler ile bağlamanız gerekmekedir. Get kullanarak bunları bağlamaya ihtiyacınız kalmaz. Get'e sadece "find" diyerek controller'ınızı bulmasını istemeniz yeterlidir. Fazladan dependency'lere ihtiyacınız yoktur:
  318 +
  319 +```dart
  320 +Controller controller = Get.find();
  321 +// Evet, inanılmaz değil mi? Get, controller'ınızı bulup getirecek. Get, milyonlarca controller tanımlanmış da olsa size her zaman doğrusunu getirecektir.
  322 +```
  323 +
  324 +Sonrasında üstte alınan controller'daki verilerinizi kullanabileceksiniz:
  325 +
  326 +```dart
  327 +Text(controller.textFromApi);
  328 +```
  329 +
  330 +### Dependency Management Hakkında Daha Fazla Bilgi
  331 +
  332 +**Dependency management'a daha derinden bakmak için [buraya](./documentation/tr_TR/dependency_management.md) tıklayabilirsiniz**
  333 +
  334 +# Utils
  335 +
  336 +## Internationalization (Uluslararasılaştırma)
  337 +
  338 +### Translations (Çeviriler)
  339 +
  340 +Translations, map halinde basit key-value değerleri tutar.
  341 +Özel translation'larınızı eklemek için bir sınıf oluşturup `Translations`sınıfını extend edebilirsiniz.
  342 +
  343 +```dart
  344 +import 'package:get/get.dart';
  345 +
  346 +class Messages extends Translations {
  347 + @override
  348 + Map<String, Map<String, String>> get keys => {
  349 + 'en_US': {
  350 + 'hello': 'Hello World',
  351 + },
  352 + 'de_DE': {
  353 + 'hello': 'Hallo Welt',
  354 + }
  355 + };
  356 +}
  357 +```
  358 +
  359 +#### Translations kullanımı
  360 +
  361 +Önecen belirlenmiş key'e sadece `.tr` eklenince `Get.locale` ve `Get.fallbackLocale` şimdiki değerleri kullanarak otomatik çeviriyi yapacaktır.
  362 +
  363 +
  364 +```dart
  365 +Text('title'.tr);
  366 +```
  367 +
  368 +#### Tekil ve çoğul çevirisi yapımı
  369 +
  370 +```dart
  371 +var products = [];
  372 +Text('singularKey'.trPlural('pluralKey', products.length, Args));
  373 +```
  374 +
  375 +#### Parametreler ile çeviri yapımı
  376 +
  377 +```dart
  378 +import 'package:get/get.dart';
  379 +
  380 +
  381 +Map<String, Map<String, String>> get keys => {
  382 + 'en_US': {
  383 + 'logged_in': 'logged in as @name with email @email',
  384 + },
  385 + 'es_ES': {
  386 + 'logged_in': 'iniciado sesión como @name con e-mail @email',
  387 + }
  388 +};
  389 +
  390 +Text('logged_in'.trParams({
  391 + 'name': 'Jhon',
  392 + 'email': 'jhon@example.com'
  393 + }));
  394 +```
  395 +
  396 +### Locales (Yerel Ayarlar)
  397 +
  398 +Locale ve translation'lar`GetMaterialApp`'in parametreleri içinde atanabilir.
  399 +
  400 +```dart
  401 +return GetMaterialApp(
  402 + translations: Messages(), //Çevirileriniz
  403 + locale: Locale('en', 'US'), //Çeviriler bu locale dilinde gösterilecek
  404 + fallbackLocale: Locale('en', 'UK'), // Eğer yanlış bir locale olması durumunda gösterilecek fallback locale
  405 +);
  406 +```
  407 +
  408 +#### Locale değiştirme
  409 +
  410 +`Get.updateLocale(locale)` çağrılarak locale güncellenebilir. Çeviriler otomatik olarak yeni locale dilinde olacaktır.
  411 +
  412 +```dart
  413 +var locale = Locale('en', 'US');
  414 +Get.updateLocale(locale);
  415 +```
  416 +
  417 +#### System locale (Yerel Sistem Ayarları)
  418 +
  419 +Sistem locale'i okumak için `Get.deviceLocale` kullanılır.
  420 +
  421 +```dart
  422 +return GetMaterialApp(
  423 + locale: Get.deviceLocale,
  424 +);
  425 +```
  426 +
  427 +## Tema Değiştirme
  428 +
  429 +Güncellemek için`GetMaterialApp`'in üstüne bir widget koymayın. Bu, kopya key'ler oluşmasını tetikler. Birçok kişi tema değiştirmek için tarih öncesi bir yöntem olan "ThemeProvider" widget'ı oluşturmayı tercih eder. **GetX™** ile buna HİÇ gerek duyulmaz.
  430 +
  431 +`Get.changeTheme`ile kendi oluşturduğunuz temanızı hızlı bir şekilde ekleyebilirsiniz:
  432 +
  433 +```dart
  434 +Get.changeTheme(ThemeData.light());
  435 +```
  436 +
  437 +`onTap`'de Temayı değiştiren bir buton oluşturmak istiyorsanız, bunun için iki **GetX™** API'sini birleştirebilirsiniz:
  438 +
  439 +- API, karanlık `Theme`'in kullanıp kullanılmadığını kontrol eder.
  440 +- `Theme` Change API'yi `onPressed`içine koyabilirsiniz:
  441 +
  442 +```dart
  443 +Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());
  444 +```
  445 +
  446 +`.darkmode` aktif hale geldiğinde, tıklandığında _light theme_ 'e döner, _light theme_ aktif olduğunda, _dark theme_'e geçer.
  447 +
  448 +## GetConnect
  449 +
  450 +GetConnect backend ile frontend'in http ya da websockets ile kolayca iletişime geçmesini sağlar.
  451 +
  452 +### Varsayılan Ayarlar
  453 +
  454 +Sadece GetConnect'den extend ederek gelen GET/POST/PUT/DELETE/SOCKET metodlarını kullanarak Rest API ya da websockets ile kolayca iletişim kurabilirsiniz.
  455 +
  456 +```dart
  457 +class UserProvider extends GetConnect {
  458 + // Get request
  459 + Future<Response> getUser(int id) => get('http://youapi/users/$id');
  460 + // Post request
  461 + Future<Response> postUser(Map data) => post('http://youapi/users', body: data);
  462 + // File ile Post request
  463 + Future<Response<CasesModel>> postCases(List<int> image) {
  464 + final form = FormData({
  465 + 'file': MultipartFile(image, filename: 'avatar.png'),
  466 + 'otherFile': MultipartFile(image, filename: 'cover.png'),
  467 + });
  468 + return post('http://youapi/users/upload', form);
  469 + }
  470 +
  471 + GetSocket userMessages() {
  472 + return socket('https://yourapi/users/socket');
  473 + }
  474 +}
  475 +```
  476 +
  477 +### Özel Ayarlamalar
  478 +
  479 +GetConnect oldukça düzenlenebilir. Kendi base Url'nizi tanımlayabilir, cevapları ve Request'leri düzenleyebilirsiniz. Authenticator oluşturup kendiliğinden authenticate olmasını sağlayabilirsiniz. Size verilen standart decoder ile tüm request'leri ek bir ayar olmadan modellerinize aktarabilirsiniz.
  480 +
  481 +```dart
  482 +class HomeProvider extends GetConnect {
  483 + @override
  484 + void onInit() {
  485 + // Tüm request'ler jsonEncode'a gider: CasesModel.fromJson()
  486 + httpClient.defaultDecoder = CasesModel.fromJson;
  487 + httpClient.baseUrl = 'https://api.covid19api.com';
  488 + // baseUrl = 'https://api.covid19api.com'; //baseUrl'yi bu şekilde tanımlar
  489 + // Http ve websockets kullanılmış ise [httpClient] instance'ına ihtiyaç yoktur.
  490 +
  491 +
  492 + // Gelen tüm request'ler "apikey"'in header özelliğine gier.
  493 + httpClient.addRequestModifier((request) {
  494 + request.headers['apikey'] = '12345678';
  495 + return request;
  496 + });
  497 +
  498 + // Eğer sunucu "Brazilya"'dan bir veri gönderse bile
  499 + // response'dan veriyi kaldırdığın için kullanıcılar göremez.
  500 + // response önceden getirişmiş olsa bile
  501 + httpClient.addResponseModifier<CasesModel>((request, response) {
  502 + CasesModel model = response.body;
  503 + if (model.countries.contains('Brazil')) {
  504 + model.countries.remove('Brazilll');
  505 + }
  506 + });
  507 +
  508 + httpClient.addAuthenticator((request) async {
  509 + final response = await get("http://yourapi/token");
  510 + final token = response.body['token'];
  511 + // header veriliyor
  512 + request.headers['Authorization'] = "$token";
  513 + return request;
  514 + });
  515 +
  516 + // HttpStatus, HttpStatus.unauthorized ise
  517 + // Autenticator 3 defa çağırılır.
  518 + httpClient.maxAuthRetries = 3;
  519 + }
  520 + }
  521 +
  522 + @override
  523 + Future<Response<CasesModel>> getCases(String path) => get(path);
  524 +}
  525 +```
  526 +
  527 +## GetPage Middleware
  528 +
  529 +GetPage'in GetMiddleWare listesi oluşturan ve bunları özel bir sırada çalıştıran bir özelliği vardır.
  530 +
  531 +**Not**: GetPage, Middlewares içeriyor ise bu sayfanın tüm çocukları da aynı middlewares'i otomatik olarak içerir.
  532 +
  533 +### Priority (Öncelik)
  534 +
  535 +Middlewares'in sıralı çalışması için GetMiddleware'lerin priority'leri (öncelikleri) düzenlenmelidir.
  536 +
  537 +```dart
  538 +final middlewares = [
  539 + GetMiddleware(priority: 2),
  540 + GetMiddleware(priority: 5),
  541 + GetMiddleware(priority: 4),
  542 + GetMiddleware(priority: -8),
  543 +];
  544 +```
  545 +
  546 +Middleware'ler bu sırada çalışacaktır: **-8 => 2 => 4 => 5**
  547 +
  548 +### Redirect (Yönlendirme)
  549 +
  550 + Çağrılan route'un sayfası arandığında, fonsyon çağırılmış olacaktır. Redirect için RouteSettings kullanılır. Name değeri null verilebilir ve bu olduğu zaman herhangi bir redirect olmayacaktır.
  551 +
  552 +```dart
  553 +RouteSettings redirect(String route) {
  554 + final authService = Get.find<AuthService>();
  555 + return authService.authed.value ? null : RouteSettings(name: '/login')
  556 +}
  557 +```
  558 +
  559 +### onPageCalled
  560 +
  561 +Bu fonsyon, herhangi bir şey oluşmadan önce sayfa çağırılmak istenildiğinde kullanılır. Sayfada bir şey değiştirmek için ya da yeni bir sayfa vermek için kullanabilirsiniz.
  562 +
  563 +```dart
  564 +GetPage onPageCalled(GetPage page) {
  565 + final authService = Get.find<AuthService>();
  566 + return page.copyWith(title: 'Welcome ${authService.UserName}');
  567 +}
  568 +```
  569 +
  570 +### OnBindingsStart
  571 +
  572 +Bu fonsyon Bindings başlatılmadan hemen önce çalışır.
  573 +Bu sayfa için Bindings'i şu şekilde değiştirebilirsiniz.
  574 +
  575 +```dart
  576 +List<Bindings> onBindingsStart(List<Bindings> bindings) {
  577 + final authService = Get.find<AuthService>();
  578 + if (authService.isAdmin) {
  579 + bindings.add(AdminBinding());
  580 + }
  581 + return bindings;
  582 +}
  583 +```
  584 +
  585 +### OnPageBuildStart
  586 +
  587 +Bu fonsyon Bindings başlatıldıktan hemen sonra çalışır.
  588 +Bindings oluşturulduktan hemen sonra ve widget sayfası oluşturulmadan önce kullanabilirsiniz.
  589 +
  590 +```dart
  591 +GetPageBuilder onPageBuildStart(GetPageBuilder page) {
  592 + print('bindings are ready');
  593 + return page;
  594 +}
  595 +```
  596 +
  597 +### OnPageBuilt
  598 +
  599 +Bu fonskyon GetPage.page fonskyonu çağrıldıktan hemen sonra çalışır ve fonksyonun sonucunu verir. Sonrasında gösterilecek widget'ı alır.
  600 +
  601 +### OnPageDispose
  602 +
  603 +Bu fonsyon sayfadaki ilgili tüm objelerin (Controllers, views, ...) dispose olmasından hemen sonra çalışır.
  604 +
  605 +## Advanced APIs (Gelişmiş API'ler)
  606 +
  607 +```dart
  608 +// currentScreen'deki arg'ı verir
  609 +Get.arguments
  610 +
  611 +// Önceki route'un name'ini verir.
  612 +Get.previousRoute
  613 +
  614 +// Erişmek için raw route'u verir. Örnek olarak: rawRoute.isFirst()
  615 +Get.rawRoute
  616 +
  617 +// GetObserver'dan Routing API'ye erişim verir.
  618 +Get.routing
  619 +
  620 +// Snackbar açık mı kontrolü yaplır.
  621 +Get.isSnackbarOpen
  622 +
  623 +// Dialog açık mı kontrolü yaplır.
  624 +Get.isDialogOpen
  625 +
  626 +// Bottomsheet açık mı kontrolü yaplır.
  627 +Get.isBottomSheetOpen
  628 +
  629 +// Tek route kaldırılır.
  630 +Get.removeRoute()
  631 +
  632 +// predicate, true döndürene kadar terarlanarak geri gelir.
  633 +Get.until()
  634 +
  635 +// Yeni route a gider ve eski tüm route'ları, predicate, true döndürene kadar kaldırır.
  636 +Get.offUntil()
  637 +
  638 +// named route'a gider ve eski tüm route'ları, predicate, true döndürene kadar kaldırır.
  639 +Get.offNamedUntil()
  640 +
  641 +//Hangi platformda çalıştığı kontrol edilir.
  642 +GetPlatform.isAndroid
  643 +GetPlatform.isIOS
  644 +GetPlatform.isMacOS
  645 +GetPlatform.isWindows
  646 +GetPlatform.isLinux
  647 +GetPlatform.isFuchsia
  648 +
  649 +//Cihaz türü kontrol edilir.
  650 +GetPlatform.isMobile
  651 +GetPlatform.isDesktop
  652 +//Web'de tüm platformlar bağımsız olarak desteklenir!
  653 +//Bir tarayıcının içinde çalışıp çalışmadığınızı anlayabilirsiniz
  654 +//Windows, iOS, OSX, Android, vs. gibi
  655 +GetPlatform.isWeb
  656 +
  657 +
  658 +// Aşağıdakine eşittir : MediaQuery.of(context).size.height,
  659 +// fakat immutable'dır (sabittir).
  660 +Get.height
  661 +Get.width
  662 +
  663 +// Navigator'e şimdiki context'i verir.
  664 +Get.context
  665 +
  666 +// Önde olan snackbar/dialog/bottomsheet'a nerede olursanız olun context'i verir.
  667 +Get.contextOverlay
  668 +
  669 +// Not: aşağıdaki metodlar context üzerine olan extension'lardır.
  670 +// UI'ın herhangi bir yerinde context'e erişebilirsiniz ve istediğiniz yerde kullanabilirsiniz.
  671 +
  672 +// Eğer değişken bir height/width verileri varsa (örnek olarak Masaüstü ya da tarayıcı gibi ölçeği değişebilen pencereler) context'i kullanmaya ihtiyacınız vardır.
  673 +context.width
  674 +context.height
  675 +
  676 +// Size ekranın yarısını, üçte birini vb. tanımlamayı sağlar.
  677 +// Responsive uygulamalar için kullanışlıdır.
  678 +// param dividedBy (double) optional - default: 1
  679 +// param reducedBy (double) optional - default: 0
  680 +context.heightTransformer()
  681 +context.widthTransformer()
  682 +
  683 +/// MediaQuery.of(context).size'a benzer
  684 +context.mediaQuerySize()
  685 +
  686 +/// MediaQuery.of(context).padding'e benzer
  687 +context.mediaQueryPadding()
  688 +
  689 +/// MediaQuery.of(context).viewPadding'e benzer
  690 +context.mediaQueryViewPadding()
  691 +
  692 +/// MediaQuery.of(context).viewInsets;'e benzer
  693 +context.mediaQueryViewInsets()
  694 +
  695 +/// MediaQuery.of(context).orientation;'a benzer
  696 +context.orientation()
  697 +
  698 +/// Cihazın yatay modda olup olmadığını kontrol eder.
  699 +context.isLandscape()
  700 +
  701 +/// Cihazın dikey modda olup olmadığını kontrol eder.
  702 +context.isPortrait()
  703 +
  704 +/// MediaQuery.of(context).devicePixelRatio;'ya benzer
  705 +context.devicePixelRatio()
  706 +
  707 +/// MediaQuery.of(context).textScaleFactor;'e benzer
  708 +context.textScaleFactor()
  709 +
  710 +/// Ekranın en kısa kenarını getirir
  711 +context.mediaQueryShortestSide()
  712 +
  713 +/// width 800'den büyük ise true döndürür.
  714 +context.showNavbar()
  715 +
  716 +/// Kısa kenar 600p'den küçük ise true döndürür.
  717 +context.isPhone()
  718 +
  719 +/// Kısa kenar 600p'den büyük ise true döndürür.
  720 +context.isSmallTablet()
  721 +
  722 +/// Kısa kenar 720p'den büyük ise true döndürür.
  723 +context.isLargeTablet()
  724 +
  725 +/// Cihaz tablet ise true döndürür.
  726 +context.isTablet()
  727 +
  728 +/// Ekran boyutuna göre <T> değerini döndürür
  729 +/// için değer verebilir:
  730 +/// watch: Kısa kenar 300'den küçük ise
  731 +/// mobile: Kısa kenar 600'den küçük ise
  732 +/// tablet: Kısa kenar 1200'den küçük ise
  733 +/// desktop: width 1200'den büyük ise
  734 +
  735 +context.responsiveValue<T>()
  736 +```
  737 +
  738 +### Opsiyonel Genel Ayarlar ve Manuel Ayarlamalar
  739 +
  740 +GetMaterialApp çoğu şeyi sizin için otomatik olarak ayarlar, ayrıca kendiniz de isterseniz Get'i manuel olarak ayarlayabilirsiniz.
  741 +
  742 +```dart
  743 +MaterialApp(
  744 + navigatorKey: Get.key,
  745 + navigatorObservers: [GetObserver()],
  746 +);
  747 +```
  748 +
  749 +`GetObserver` içinde kendi Middleware'ınızı kullanabilirsiniz ve bu hiçbir şeyi etkilemez.
  750 +
  751 +```dart
  752 +MaterialApp(
  753 + navigatorKey: Get.key,
  754 + navigatorObservers: [
  755 + GetObserver(MiddleWare.observer) // Burası
  756 + ],
  757 +);
  758 +```
  759 +
  760 +`Get` için _Global Settings_ oluşturabilirsiniz. Herhangi bir route'a push yapmadan önce kodunuza `Get.config` eklemeniz yeterli.
  761 +Ya da doğrudan `GetMaterialApp` içinde tanımlayabilirsiniz.
  762 +
  763 +```dart
  764 +GetMaterialApp(
  765 + enableLog: true,
  766 + defaultTransition: Transition.fade,
  767 + opaqueRoute: Get.isOpaqueRouteDefault,
  768 + popGesture: Get.isPopGestureEnable,
  769 + transitionDuration: Get.defaultDurationTransition,
  770 + defaultGlobalState: Get.defaultGlobalState,
  771 +);
  772 +
  773 +Get.config(
  774 + enableLog = true,
  775 + defaultPopGesture = true,
  776 + defaultTransition = Transitions.cupertino
  777 +)
  778 +```
  779 +
  780 +İsteğe bağlı olarak tüm logging mesajlarını `Get` üzerinden yönlendirebilirsiniz.
  781 +Kendi istediğiniz logging paketinizi kullanmak
  782 +ve oradaki log'ları yakalamak istiyorsanız:
  783 +
  784 +```dart
  785 +GetMaterialApp(
  786 + enableLog: true,
  787 + logWriterCallback: localLogWriter,
  788 +);
  789 +
  790 +void localLogWriter(String text, {bool isError = false}) {
  791 + // istediğiniz logging paketine mesajı aktarır
  792 + // eğer, enableLog: false ise log mesajları bu callback içine gönderilir
  793 + // GetConfig.isLogEnable aracılığıyla isterseniz kontrol edebilirsiniz
  794 +}
  795 +
  796 +```
  797 +
  798 +### Local State Widgets (Yerel Durum Widgetları)
  799 +
  800 +Bu widget'lar tek bir değeri kontrol etmenize ve durumu geçici ya da yerel olarak tutmanızı sağlar.
  801 +Reactive ve simple olan yapılar içerir.
  802 +Örneğin bunları `TextField` içindeki obscureText parametresine bağlayabilirsiniz. İsterseniz kendinizinkini (Expandable Panel vs.) de oluşturabilirsiniz ya da `Scaffold`'daki body'nin içeriği değişirken `BottomNavigationBar` içindeki current index'i değiştirebilirsiniz.
  803 +
  804 +#### ValueBuilder
  805 +
  806 +Veri güncellemenin bir yolu olan `StatefulWidget`'daki `.setState` yapısının basitleştirilmiş halidir.
  807 +
  808 +```dart
  809 +ValueBuilder<bool>(
  810 + initialValue: false,
  811 + builder: (value, updateFn) => Switch(
  812 + value: value,
  813 + onChanged: updateFn, // tamamen aynısı! ( newValue ) => updateFn( newValue ) yapısını da kullanabilirsiniz
  814 + ),
  815 + // eğer builder metodu dışından bir çağırma işlemi yapılacak ise
  816 + onUpdate: (value) => print("Value updated: $value"),
  817 + onDispose: () => print("Widget unmounted"),
  818 +),
  819 +```
  820 +
  821 +#### ObxValue
  822 +
  823 +[`ValueBuilder`](#valuebuilder)'a oldukça benzer olmasının yanında bu Reactive halidir. Rx nesnesine aktarabilir ( .obs yapısını hatıladınız mı?) ve otomatik olarak güncellenmensini sağlayabilirsiniz, resmen muhteşem değil mi ?
  824 +
  825 +```dart
  826 +ObxValue((data) => Switch(
  827 + value: data.value,
  828 + onChanged: data, // Rx, çağrılabilen fonsyon içerir. (flag) => data.value = flag şeklinde kullanılablir.
  829 + ),
  830 + false.obs,
  831 +),
  832 +```
  833 +
  834 +## Faydalı Ipuçları
  835 +
  836 +`.obs` yapıları olan gözlemlenebilirler ( _Rx_ tipleri olarak da bilinirler) oldukça çeşitli internal metodlara ve operatörlere sahiptirler.
  837 +
  838 +> `.obs` yapısının gerçek değer olduğunu düşünenler oldukça yaygındır fakat bu yanlış bir düşüncedir.
  839 +> Değişkenleri, Type declaration yapmaktan kaçınmalıyız. Çünkü Dart'ın derleyicisi zaten bunu anlayacak kadar zekidir.
  840 +> Kodunuzu daha temiz gösterir fakat:
  841 +
  842 +```dart
  843 +var message = 'Hello world'.obs;
  844 +print( 'Message "$message" has Type ${message.runtimeType}');
  845 +```
  846 +
  847 +`message`, gerçek String Type değerini yazdırsa bile aslında bu bir **RxString** Type değeridir!
  848 +
  849 +Yani `message.substring( 0, 4 )` şeklinde kullanmazsınız.
  850 + _observable_ içindeki gerçek `value`'ya (değere) erişmelisiniz.
  851 +En çok "kullanılan yol" `.value` yapısı ile erişmektir fakat şu şekilde kullanabileceğiniz bir yol daha var...
  852 +
  853 +
  854 +```dart
  855 +final name = 'GetX'.obs;
  856 +// eğer değer şimdikinden farklı ise, sadece stream'i "günceller"
  857 +name.value = 'Hey';
  858 +
  859 +// Tüm Rx özellikleri "çağrılabilir" ve geriye yeni bir değer döndürür.
  860 +// Fakat bu yaklaşım `null` değerleri kabul etmez, sonucunda UI rebuild (tekrardan oluşturulmaz) edilmez.
  861 +name('Hello');
  862 +
  863 +// getter yapmak gibi, 'Hello'yazdırır.
  864 +
  865 +name() ;
  866 +
  867 +/// numbers:
  868 +
  869 +final count = 0.obs;
  870 +
  871 +// Tüm non mutable (değişken olmayan) işlemleri num primitives üzerinden yapabilirsiniz.
  872 +count + 1;
  873 +
  874 +// Dikkat edin! Bu sadece `count` değerinin 'final' olmayıp 'var' olduğu değerlerde mümkündür.
  875 +count += 1;
  876 +
  877 +// Ayrıca değerleri kıyaslayabilirsiniz:
  878 +count > 2;
  879 +
  880 +/// booleans:
  881 +
  882 +final flag = false.obs;
  883 +
  884 +// değer true/false arasında değişir.
  885 +flag.toggle();
  886 +
  887 +
  888 +/// tüm tipler için:
  889 +
  890 +// "value"'ları null'a çevirir.
  891 +flag.nil();
  892 +
  893 +// Tüm toString(), toJson() işlemleri `value`'ya aktarılır.
  894 +print( count ); // RxInt içinden `toString()` çağrılır.
  895 +
  896 +final abc = [0,1,2].obs;
  897 +// Değeri bir json Array (dizi) yapısına çevirir ve RxList şeklinde yazdırır.
  898 +// Json tüm Rx tipleri tarafından desteklenir.
  899 +print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}');
  900 +
  901 +// RxMap, RxList ve RxSet kendi native tiplerinden extend edilen özel Rx tipleridir.
  902 +// Fakat List ile çalışmak normal listelerle çalışmak gibidir. Reaktiv olmasına rağmen.
  903 +abc.add(12); // '12' listeye eklenir ve stream GÜNCELLENİR.
  904 +abc[3]; // List'deki gibi 3. index okunur.
  905 +
  906 +
  907 +// Rx ve value ile çalışmak aynıdır fakat hashCode her zaman value'dan alınır.
  908 +final number = 12.obs;
  909 +print( number == 12 ); // çıktı: true
  910 +
  911 +/// Özel Rx Modelleri:
  912 +
  913 +
  914 +// toJson(), toString() child'a gönderilir. Böylelikle override'ları onlara implement edebilirsiniz ve doğrudan gözlemlenebiliri print() edebilirsiniz.
  915 +
  916 +class User {
  917 + String name, last;
  918 + int age;
  919 + User({this.name, this.last, this.age});
  920 +
  921 + @override
  922 + String toString() => '$name $last, $age years old';
  923 +}
  924 +
  925 +final user = User(name: 'John', last: 'Doe', age: 33).obs;
  926 +
  927 +// `user`,"reactive" yapıdadır. Fakat içinde özellikleri DEĞİLDİR.
  928 +// Yani eğer içindeki bazı değerleri değiştirirsek
  929 +user.value.name = 'Roi';
  930 +//widget, rebuild olmayacaktır!,
  931 +//`Rx`, user içindeki bir şeyi değiştirdiğinizde, bundan haberi olmayacaktır.
  932 +// Özel sınıflar oluşturmak için, manuel olarak değişiklikleri "notify" etmeliyiz.
  933 +user.refresh();
  934 +
  935 +// Ya da `update()` metodunu kullanabiliriz
  936 +user.update((value){
  937 + value.name='Roi';
  938 +});
  939 +
  940 +print( user );
  941 +```
  942 +## StateMixin
  943 +
  944 +`UI` state ile başa çıkmanın başka bir yolu da `StateMixin<T>` kullanmaktır.
  945 +Bunu implement yapmak için, controller'ınıza `with` kullanarak yanına `StateMixin<T>` eklemekle olur.
  946 +Bu sizin T modelini kullanmanızı sağlar.
  947 +
  948 +
  949 +``` dart
  950 +class Controller extends GetController with StateMixin<User>{}
  951 +```
  952 +
  953 +`change()` metodu istediğiniz yerde State'i değiştirmemizi sağlar.
  954 +Veri(data) ve durum(status) aktarmak için kullanılan yol:
  955 +
  956 +```dart
  957 +change(data, status: RxStatus.success());
  958 +```
  959 +
  960 +RxStatus şu durumları kullanmanızı sağlar:
  961 +
  962 +``` dart
  963 +RxStatus.loading();
  964 +RxStatus.success();
  965 +RxStatus.empty();
  966 +RxStatus.error('message');
  967 +```
  968 +
  969 +UI'ın içinde temsil edilmesi için şu şekilde kullanılır:
  970 +
  971 +```dart
  972 +class OtherClass extends GetView<Controller> {
  973 + @override
  974 + Widget build(BuildContext context) {
  975 + return Scaffold(
  976 +
  977 + body: controller.obx(
  978 + (state)=>Text(state.name),
  979 +
  980 + // Kendi yüklenme göstergenizi (loading indicator) buraya eklebilirsiniz
  981 + // hali hazırda gelen yapı şudur: Center(child:CircularProgressIndicator())
  982 + onLoading: CustomLoadingIndicator(),
  983 + onEmpty: Text('No data found'),
  984 +
  985 + // Keni hata widget'ınızı buraya yazabilirsiniz
  986 + // hali hazırda gelen yapı şudur: Center(child:Text(error))
  987 + onError: (error)=>Text(error),
  988 + ),
  989 + );
  990 +}
  991 +```
  992 +
  993 +#### GetView
  994 +
  995 +Bu widget'ı çok seviyorum, oldukça basit ve çok kullanışlı!
  996 +
  997 +`const Stateless` Widget, `Controller`'ı tanımlamak için `controller` özelliği içerir.
  998 +
  999 +```dart
  1000 + class AwesomeController extends GetController {
  1001 + final String title = 'My Awesome View';
  1002 + }
  1003 +
  1004 + // controller'ınızı register etmek için bunu kullandığınız `Type`'a geçirmeyi asla unutmayın.
  1005 + class AwesomeView extends GetView<AwesomeController> {
  1006 + @override
  1007 + Widget build(BuildContext context) {
  1008 + return Container(
  1009 + padding: EdgeInsets.all(20),
  1010 + child: Text(controller.title), // sadece `controller.something` deyin
  1011 + );
  1012 + }
  1013 + }
  1014 +```
  1015 +
  1016 +#### GetResponsiveView
  1017 +
  1018 +Responsive view oluşturmak için bu widget'tan extend edilir.
  1019 +Bu widget ekran size ve type hakkında bilgiler içeren
  1020 +`screen` özelliğini taşır.
  1021 +
  1022 +##### Nasıl kullanılır?
  1023 +
  1024 +build yapmanız için 2 yönteminiz vardır.
  1025 +
  1026 +- build yapmak için `builder` metodu ile widget döndürmek
  1027 +- `desktop`, `tablet`,`phone`, `watch` metodları ile
  1028 + bu özel metodlar ekran türü bu metodlarla eşitlendiiği zaman build metodunu tetikler.
  1029 + Mesela ekran [ScreenType.Tablet] ise `tablet` metodu çalışrıtılacaktır.
  1030 + **Not:** Eğer bu metodu kullanırsanız, lütfen `alwaysUseBuilder` özelliğini `false` olarak işaretleyin.
  1031 +
  1032 +`settings` özelliği sayesinde ekranın türüne göre genişlik limiti koyabilirsiniz.
  1033 +
  1034 +![örnek](https://github.com/SchabanBo/get_page_example/blob/master/docs/Example.gif?raw=true)
  1035 +Bu ekranın kodları
  1036 +[burada](https://github.com/SchabanBo/get_page_example/blob/master/lib/pages/responsive_example/responsive_view.dart)
  1037 +
  1038 +#### GetWidget
  1039 +
  1040 +Çoğu kişinin widget'lar hakkında hiçbir fikri yok ya da kullanırken inanılmaz kafası karışıyor.
  1041 +Bu kullanım oldukça nadir fakat özel: Controller `caches`'leme işlemi _cache_ yüzünden asla bir `const Stateless` oluşamaz.
  1042 +
  1043 +> Peki ne zaman Controller'ı "cache"'yemeye ihtiyacınız olacak?
  1044 +
  1045 +"Çok da yaygın olmayan" bir **GetX** özelliğini kullanıyorsanız: `Get.create()`.
  1046 +
  1047 +`Get.create(()=>Controller())` yapısı siz her `Get.find<Controller>()` dediğinizde size yeni bir `Controller` oluşturacak.
  1048 +
  1049 +`GetWidget`'ın ışığı burada parlıyor. Örnek olarak bir listede
  1050 +
  1051 +Todo ögelerini tutmak istiyorsanız kullanılır. Eğer widget'ın "rebuilt" olursa, yapı yine aynı controller nesnesini tutmaya devam edecektir.
  1052 +
  1053 +#### GetxService
  1054 +
  1055 +Bu sınıf `GetxController`' bezer. Uygulamanın lifecycle'larını (hayat döngüsü metodlarını) içerir ( `onInit()`, `onReady()`, `onClose()`).
  1056 +Fakat içinde hiçbir mantıksal yapı bulunmaz. Sadece **GetX**'in Dependency Injection sistemini bilgilendirir.
  1057 +
  1058 +Bunun alt sınıfları, memory (bellekten) hiçbir şekilde **kaldırılamaz**.
  1059 +
  1060 +
  1061 +Bu yöntem "Servislerinizi" tutmak için oldukça kullanışlıdır. Servisleriniz bu şekilde her zaman ulaşılabilir ve aktif olur. `Get.find()` metodu buna yeter. Örnek olarak:`ApiService`, `StorageService`, `CacheService`.
  1062 +
  1063 +
  1064 +```dart
  1065 +Future<void> main() async {
  1066 + await initServices(); /// SERVİSLERİN BAŞLATILMASI BEKLENİR
  1067 + runApp(SomeApp());
  1068 +}
  1069 +
  1070 +/// Servislerinizi Flutter uygulaması çalışmadan önce başlatılması oldukça mantıklı bir harekettir.
  1071 +/// Uygulama akışını kontrol edebilirsiniz. (belki de birkaç tane Tema düzenlemesi ya da
  1072 +/// apiKey, kulllanıcıdan gelen dil tanımlaması gibi düzenlemeler yapmanız lazımdır...Bu durumna SettingService'i ApiService'den önce çalışması gerekmektedir.
  1073 +/// GetMaterialApp() 'in rebuild yapmasına gerek yoktur. Çünkü değerleri doğrudan alır.
  1074 +void initServices() async {
  1075 + print('starting services ...');
  1076 + /// Burası sizin get_storage, hive, shared_pref gibi yükelemeleri yaptığınız yer.
  1077 + /// ya da daha fazla özellik bağlamak ve ya async yapıları kullanmak için
  1078 + await Get.putAsync(() => DbService().init());
  1079 + await Get.putAsync(SettingsService()).init();
  1080 + print('All services started...');
  1081 +}
  1082 +
  1083 +class DbService extends GetxService {
  1084 + Future<DbService> init() async {
  1085 + print('$runtimeType delays 2 sec');
  1086 + await 2.delay();
  1087 + print('$runtimeType ready!');
  1088 + return this;
  1089 + }
  1090 +}
  1091 +
  1092 +class SettingsService extends GetxService {
  1093 + void init() async {
  1094 + print('$runtimeType delays 1 sec');
  1095 + await 1.delay();
  1096 + print('$runtimeType ready!');
  1097 + }
  1098 +}
  1099 +
  1100 +```
  1101 +
  1102 +`GetxService`'lerini silmenin tek bir yolu vardır o da `Get.reset()`.
  1103 +Bu yöntem uygulamanıza "Hot Reboot" yapmak gibidir. Eğer uygulamanızın hayat süresi boyunca mutlaka kalıcılığı olmasını istediğiniz bir sınıfın nesnesini oluşturmak istediğiniz zaman `GetxService`'i kullanın.
  1104 +
  1105 +
  1106 +### Testler
  1107 +
  1108 +Controller'larınızı lifecycle'ları (hayat döngüleri) dahil olmak üzere diğer sınıflar gibi test edebilirsiniz:
  1109 +
  1110 +```dart
  1111 +class Controller extends GetxController {
  1112 + @override
  1113 + void onInit() {
  1114 + super.onInit();
  1115 + //Değeri name2 ile değiştirme
  1116 +
  1117 + name.value = 'name2';
  1118 + }
  1119 +
  1120 + @override
  1121 + void onClose() {
  1122 + name.value = '';
  1123 + super.onClose();
  1124 + }
  1125 +
  1126 + final name = 'name1'.obs;
  1127 +
  1128 + void changeName() => name.value = 'name3';
  1129 +}
  1130 +
  1131 +void main() {
  1132 + test('''
  1133 +Test the state of the reactive variable "name" across all of its lifecycles''',
  1134 + () {
  1135 + /// Controller'ınızı lifecycle dışında test edebilirsiniz.
  1136 + /// Fakat bunu GetX dependency injection kullanmadığınız taktirde
  1137 + /// kullanmanız önerilmiyor.
  1138 + final controller = Controller();
  1139 + expect(controller.name.value, 'name1');
  1140 +
  1141 + /// Eğer kullanıyorsanı istediğiniz her şeyi test edebilirsiniz.
  1142 + /// Her lifecycle sonrası uygulamanızın durumu dahil olmak üzere.
  1143 + Get.put(controller); // onInit çağrıldıktan sonra
  1144 + expect(controller.name.value, 'name2');
  1145 +
  1146 + /// Bu fonksoynu test edin
  1147 + controller.changeName();
  1148 + expect(controller.name.value, 'name3');
  1149 +
  1150 + /// onClose çağrıldıktan sonra
  1151 + Get.delete<Controller>();
  1152 +
  1153 + expect(controller.name.value, '');
  1154 + });
  1155 +}
  1156 +```
  1157 +
  1158 +#### Ipuçları
  1159 +
  1160 +##### Mockito or mocktail
  1161 +Eğer GetxController/GetxService'inizi mock yapmaya ihtiyacınız varsa GetxController'dan extend etmeniz ve Mock ile mixin'lemelisiniz.
  1162 +
  1163 +```dart
  1164 +class NotificationServiceMock extends GetxService with Mock implements NotificationService {}
  1165 +```
  1166 +
  1167 +##### Using Get.reset()
  1168 +Eğer widget'ları ya da widget grupllarını test etmek istiyorsanız, testinizin sonunda Get.reset'i kullanın ya da önceki testinizden kalma tüm ayarları sıfırlayın.
  1169 +
  1170 +##### Get.testMode
  1171 +Eğer controller'larınızın içinden navigation kullanmak istiyorsanız. Main'den önce `Get.testMode = true` şeklinde kullanın.
  1172 +
  1173 +
  1174 +# 2.0 Ile Gelen Büyük Değişiklikler
  1175 +
  1176 +1- Rx Types :
  1177 +
  1178 +| Önce | Sonra |
  1179 +| ------- | ---------- |
  1180 +| StringX | `RxString` |
  1181 +| IntX | `RxInt` |
  1182 +| MapX | `RxMap` |
  1183 +| ListX | `RxList` |
  1184 +| NumX | `RxNum` |
  1185 +| DoubleX | `RxDouble` |
  1186 +
  1187 +RxController ve GetBuilder şimdi birleştiler. Artık hangi controller'ı kullanmak istediğinizi hatırlamak zorunda değilsiniz. SAdece GetxController diyerek halledin. Bu simple state management ve reactive ile düzgün çalışacaktır.
  1188 +
  1189 +2- NamedRoutes
  1190 +
  1191 +Önce:
  1192 +
  1193 +```dart
  1194 +GetMaterialApp(
  1195 + namedRoutes: {
  1196 + '/': GetRoute(page: Home()),
  1197 + }
  1198 +)
  1199 +```
  1200 +
  1201 +Şimdiki:
  1202 +
  1203 +```dart
  1204 +GetMaterialApp(
  1205 + getPages: [
  1206 + GetPage(name: '/', page: () => Home()),
  1207 + ]
  1208 +)
  1209 +```
  1210 +Neden bu değişiklik?
  1211 +
  1212 +Genellikle, hangi sayfanın bir parametreden görüntüleneceğine veya bir giriş belirteciden görüntüleneceğine karar vermek gerekebilir, önceki yaklaşım buna izin vermediği için esnek değildi.
  1213 +Sayfayı bir fonksiyona sokmak, RAM tüketimini önemli ölçüde azaltır, çünkü rotalar uygulama başlatılmasından bu yana belleğe tahsis edilmeyecek ve aynı zamanda bu tür bir yaklaşım yapmasına izin verilmeyecek:
  1214 +
  1215 +```dart
  1216 +
  1217 +GetStorage box = GetStorage();
  1218 +
  1219 +GetMaterialApp(
  1220 + getPages: [
  1221 + GetPage(name: '/', page:(){
  1222 + return box.hasData('token') ? Home() : Login();
  1223 + })
  1224 + ]
  1225 +)
  1226 +```
  1227 +
  1228 +# Neden Getx?
  1229 +
  1230 +1- Birçok kez Flutter güncellendikten sonra, birçok paket çalışmaz hale gelecek. Genelde derleme hataları gerçekleşir. Bu hataların hala cevabı olmayabilir. Geliştiricinin bu hatanın nerden geldiğini bilmesi gereklidir. Sonrasında bu hatayı izleyip bunun hakkında repository'de issue açması ve sorunun çözülmesini beklemelidir. Get, geliştirme için gereken ana kaynaklarını (State, dependency ve route management) merkezde toplar, pubspec'e tek bir paket eklemeye izin verir ve çalışmaya başlar. Flutter güncellendikten sonra tek yapmanız gereken Get dependency'yi güncellemek ve çalışmaya başlamaktır. Get uyumluluk problemlerini de çözer. Paketler arasında genelde güncellemeler sonrası uyumsuzluklar olabilir. Get'in kendi içinde her şey birbiri ile uyumlu olduğundan bunun için endişelenmenize gerek yoktur.
  1231 +
  1232 +2- Flutter oldukça kolay kullanımı olan inanılmaz olmasının yanı sıra birçok geliştirici tarafından istenmeyen `Navigator.of(context).push (context, builder [...]` gibi ezber yapılar içerir. Get geliştirmeyi basitleştirir. Route çağırmak için 8 kod yazmak yerine sadece `Get.to(Home())` diyerek bir sonraki sayfaya geçebilirsin. Dynamic web urls ile çalışmak mevcut Flutter ile çalışırken zorlayıcı olabilir. Get ile durum tam tersi hal alır ve işleri çok kolay bir hale getirir. Flutter'da State'leri yönetmek için dependency'leri pub içerindeki yüzlerce kütüphane arasından seçmek birçok tartışmayı da beraberinde getiren bir konudur. Get sayesinde ekranda değişkeni otomatik olarak güncellemesini sağlamak için değişkeninizin sonuna ".obs" eklemek ve widget'ınızı Obx ile sarmalamak yeterlidir.
  1233 +
  1234 +3- Performansı kafaya takmayın. Flutter'ın performansı zaten çok iyi. Bir de state manager kullanırken ve blocs/stores/controllers gibi sınıflarınızı locator ile yönetirken de aynı performansı aldığınızı düşünün. İhtiyacınız olmadığında dependency'lerinizi dışarıdan çağırmak zorunda kalacaksınız. Hiç düşündünüz mü, basitçe kullandığınız controller'ınızın artık kimse tarafından kullanılmadığında kolayca bellekten silindiğini? İşte GetX bunu yapar. SmartManagement sayesinde kullanılmayan her şey endişelenmenize gerek kalmadan otomatik olarak hafızadan silinir. Bunun için bir logic yaratmaya gerek bile kalmadan, kaynakları minimum ölçüde tükettiğinize emin olabilirsiniz.
  1235 +
  1236 +4- Gerçek ayrıştırma: "View ile the business logic (iş mantığını) birbirlerinden ayırmak" kavramını duymuş olabilirsiniz. Bu sadece BLoC, MVC, MVVM'ye özgü bir özellik değildir, piyasadaki diğer standart tasarım desenlerinde de mevcuttur. Ancak bu kavram Flutter'da context kullanımına bağlı olarak kolaylaştırılabilir.
  1237 +Bir InheritedWidget bulabilmek için context'e ihtiyaç duyduğunuzda, bunu view'da yapmalı ya da parametre ile aktarmalıyız. Ben bu yöntemi oldukça çirkin buluyorum. Ayrıca bir ekip ile çalışırken View'daki iş mantığına hep bağımlı olacağız. GetX standart yaklaşımı benimsemez ve StatefulWidgets, InitState, vb. yapılarını tamamen ortadan kaldırmaz. Daha temiz bir yaklaşım sunar. Controller'ların yaşam döngüleri vardır. Mesela APIREST talebi yaptığında view'a bağlı olmak zorunda değilsin. Http çağrısı başlatmak için "onInit" kullanabilirsiniz. Veriler geldiğinde yerleştirilecektir. GEtX tamamen reaktif (cidden,stream'lerin altında çalışır) olduğu için tüm item'lar doldurulduğunda o değişkeni kullanan tüm widget'lar view'da otomatik olarak güncellenecektir. Bu UI uzmanlığına sahip kişilerin sadece widget'larla çalışmasını sağlar ve kullanıcı etkinlikleri dışında iş mantığına hiçbir şey göndermek zorunda değildir (bir düğmeye tıklamak gibi). İş mantığı ile çalışan insanlar, bunu ayrı olarak oluşturmak ve test etmek konusunda serbest olacaktır.
  1238 +
  1239 +Bu kütüphane her zaman güncellenebilir ve yeni özellikler eklenebilir olacaktır. PR ve contribute yapmakta tamamen özgürsünüz.
  1240 +
  1241 +# Topluluk
  1242 +
  1243 +## Topluluk Kanalları
  1244 +
  1245 +GetX oldukça aktif ve yardımsever bir topluluğa sahiptir. Bu framework kullanımıyla ilgili sorularınız varsa veya herhangi bir yardım istiyorsanız, lütfen topluluk kanallarımıza katılın, sorunuz daha hızlı yanıtlanacak ki bunun için en uygun yer burasıdır. Repository'de issues açabilir ve kaynak talep edebilirsiniz. GetX topluluğunun bir parçası olmaktan çekinmeyin.
  1246 +
  1247 +| **Slack** | **Discord** | **Telegram** |
  1248 +| :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- |
  1249 +| [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx) | [![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N) | [![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g) |
  1250 +
  1251 +## Nasıl katkıda bulunulur?
  1252 +
  1253 +_Projeye katkıda bulunmak ister misiniz? Sizi destekçilerimizden biri olarak öne çıkarmaktan gurur duyacağız. İşte katkıda bulunabileceğiniz ve Get'i (ve Flutter'ı) daha da iyi hale getirebileceğiniz bazı noktalar._
  1254 +
  1255 +- Readme dosyasının diğer dillere çevrilmesine yardımcı olmak.
  1256 +- Readme'ye dokümanlar eklemek (birçok Get fonsyonu henüz belgelenmedi).
  1257 +- Get'in kullanımını öğretmek için makaleler yazabilir ya da videolar çekebilirsiniz (Bunlar Readme ve gelecekte Wiki'ye eklenecek).
  1258 +- Kod ve test PR'ları önermek.
  1259 +- Yeni fonksiyonlar eklemek.
  1260 +
  1261 +Her türlü yardım için teşekkürler.
  1262 +
  1263 +
  1264 +## Makaleler ve videolar
  1265 +
  1266 +- [Flutter Getx EcoSystem package for arabic people](https://www.youtube.com/playlist?list=PLV1fXIAyjeuZ6M8m56zajMUwu4uE3-SL0) - Tutorial by [Pesa Coder](https://github.com/UsamaElgendy).
  1267 +- [Dynamic Themes in 3 lines using GetX™](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial by [Rod Brown](https://github.com/RodBr).
  1268 +- [Complete GetX™ Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI) - Route management video by Amateur Coder.
  1269 +- [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw) - State management video by Amateur Coder.
  1270 +- [GetX™ Other Features](https://youtu.be/ttQtlX_Q0eU) - Utils, storage, bindings and other features video by Amateur Coder.
  1271 +- [Firestore User with GetX | Todo App](https://www.youtube.com/watch?v=BiV0DcXgk58) - Video by Amateur Coder.
  1272 +- [Firebase Auth with GetX | Todo App](https://www.youtube.com/watch?v=-H-T_BSgfOE) - Video by Amateur Coder.
  1273 +- [The Flutter GetX™ Ecosystem ~ State Management](https://medium.com/flutter-community/the-flutter-getx-ecosystem-state-management-881c7235511d) - State management by [Aachman Garg](https://github.com/imaachman).
  1274 +- [The Flutter GetX™ Ecosystem ~ Dependency Injection](https://medium.com/flutter-community/the-flutter-getx-ecosystem-dependency-injection-8e763d0ec6b9) - Dependency Injection by [Aachman Garg](https://github.com/imaachman).
  1275 +- [GetX, the all-in-one Flutter package](https://www.youtube.com/watch?v=IYQgtu9TM74) - A brief tutorial covering State Management and Navigation by Thad Carnevalli.
  1276 +- [Build a To-do List App from scratch using Flutter and GetX](https://www.youtube.com/watch?v=EcnqFasHf18) - UI + State Management + Storage video by Thad Carnevalli.
  1277 +- [GetX Flutter Firebase Auth Example](https://medium.com/@jeffmcmorris/getx-flutter-firebase-auth-example-b383c1dd1de2) - Article by Jeff McMorris.
  1278 +- [Flutter State Management with GetX – Complete App](https://www.appwithflutter.com/flutter-state-management-with-getx/) - by App With Flutter.
  1279 +- [Flutter Routing with Animation using Get Package](https://www.appwithflutter.com/flutter-routing-using-get-package/) - by App With Flutter.
  1280 +- [A minimal example on dartpad](https://dartpad.dev/2b3d0d6f9d4e312c5fdbefc414c1727e?) - by [Roi Peker](https://github.com/roipeker)
  1 +# Dependency Management
  2 +- [Dependency Management](#dependency-management)
  3 + - [Örnek Metodlar](#örnek-metodlar)
  4 + - [Get.put()](#getput)
  5 + - [Get.lazyPut](#getlazyput)
  6 + - [Get.putAsync](#getputasync)
  7 + - [Get.create](#getcreate)
  8 + - [Metodların/Sınıfların örneklerinin kullanılması](#metodların/sınıfların-örneklerinin-kullanılması)
  9 + - [Alternatif bir instance tanımlama](#alternatif-bir-instance-tanımlama)
  10 + - [Metodlar arasındaki farklılıklar](#metodlar-arasındaki-farklılıklar)
  11 + - [Bindings](#bindings)
  12 + - [Bindings class](#bindings-class)
  13 + - [BindingsBuilder](#bindingsbuilder)
  14 + - [SmartManagement](#smartmanagement)
  15 + - [Nasıl değiştirilir?](#nasıl-değiştirilir)
  16 + - [SmartManagement.full](#smartmanagementfull)
  17 + - [SmartManagement.onlyBuilder](#smartmanagementonlybuilder)
  18 + - [SmartManagement.keepFactory](#smartmanagementkeepfactory)
  19 + - [Nasıl bindings yapılır?](#nasıl-bindings-yapılır)
  20 + - [Notlar](#notlar)
  21 +
  22 +Get, yalnızca 1 satır kodla, Provider context'i olmadan, inheritedWidget olmadan Bloc veya Controller ile aynı sınıfı almanızı sağlayan basit ve güçlü bir dependency manager'a (bağımlılık yöneticisine) sahiptir:
  23 +
  24 +```dart
  25 +Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
  26 +```
  27 +
  28 +Sınıfınızı kullandığınız sınıf içinde somutlaştırmak yerine, onu uygulamanız genelinde kullanılabilir hale getirecek olan Get örneğinde somutlaştırıyorsunuz.
  29 +Böylece denetleyicinizi (veya Bloc sınıfını) normal şekilde kullanabilirsiniz.
  30 +
  31 +- Not: Get's State Manager kullanıyorsanız, view'e controller'ı bağlamayı kolaylaştıracak olan [Bindings](#bindings) API'sine daha fazla dikkat edin.
  32 +- Not²: Get dependency management (bağımlılık yönetimi) paketin diğer bölümlerinden ayrılmıştır, bu nedenle örneğin uygulamanız zaten bir state manager (durum yöneticisi) kullanıyorsa (herhangi biri, önemli değil), bunu değiştirmeniz gerekmez, dependency injection (bağımlılık enjeksiyonunu) kullanabilirsiniz.
  33 +
  34 +## Örnek metodlar
  35 +Metodlar ve configurable parameters (yapılandırılabilir parametreleri) şunlardır:
  36 +
  37 +### Get.put()
  38 +
  39 +Dependency (bağımlılık) eklemenin en yaygın yolu. Örneğin;
  40 +
  41 +```dart
  42 +Get.put<SomeClass>(SomeClass());
  43 +Get.put<LoginController>(LoginController(), permanent: true);
  44 +Get.put<ListItemController>(ListItemController, tag: "some unique string");
  45 +```
  46 +
  47 +Put kullanırken ayarlayabileceğiniz tüm seçenekler şunlardır:
  48 +```dart
  49 +Get.put<S>(
  50 + // Zorunlu: Controller veya herhangi bir şey gibi kaydetmek istediğiniz sınıf
  51 + // not: "S", herhangi bir türde bir sınıf olabileceği anlamına gelir
  52 + S dependency
  53 +
  54 + // isteğe bağlı: bu, aynı türden birden çok sınıf içindir
  55 + // normalde Get.find<Controller>() kullanarak bir sınıf aldığınız için,
  56 + // hangi örneğe ihtiyacınız olduğunu söylemek için "tag" kullanmanız gerekir
  57 + // benzersiz dize olmalıdır
  58 + String tag,
  59 +
  60 + // isteğe bağlı: varsayılan olarak, get artık kullanılmadıktan sonra örnekleri elden çıkarır (örneğin,
  61 + // gizli bir view'in controller'ı), ancak instance'a ihtiyacınız olabilir
  62 + // tüm uygulama boyunca orada tutulacak, Shared Preferences örneği veya başka bir şey gibi
  63 + // yani bunu kullanıyorsun
  64 + // varsayılan olarak false
  65 + bool permanent = false,
  66 +
  67 + // isteğe bağlı: bir testte abstract(soyut) bir sınıf kullandıktan sonra, onu başka bir sınıfla değiştirmenize ve testi takip etmenize olanak tanır.
  68 + // varsayılan olarak false
  69 + bool overrideAbstract = false,
  70 +
  71 + // optional: allows you to create the dependency using function instead of the dependency itself.
  72 + //isteğe bağlı: dependency'nin(bağımlılığın) kendisi yerine fonksiyonu kullanarak dependency(bağımlılık) oluşturmanıza olanak tanır.
  73 + //bu yaygın olarak kullanılmaz
  74 + InstanceBuilderCallback<S> builder,
  75 +)
  76 +```
  77 +
  78 +### Get.lazyPut
  79 +Bir bağımlılığı lazyLoad ile yalnızca kullanıldığında somutlaştırılacak şekilde yüklemek mümkündür. Hesaplamalı expensive sınıflar için veya birkaç sınıfı tek bir yerde başlatmak istiyorsanız (Bindings sınıfında olduğu gibi) çok kullanışlıdır ve o zaman o sınıfı kullanmayacağınızı bilirsiniz.
  80 +
  81 +```dart
  82 +/// ApiMock yalnızca Get.find<ApiMock>'u ilk kez kullandığında çağrılacak
  83 +Get.lazyPut<ApiMock>(() => ApiMock());
  84 +
  85 +Get.lazyPut<FirebaseAuth>(
  86 + () {
  87 + // ... gerekirse biraz mantık
  88 + return FirebaseAuth();
  89 + },
  90 + tag: Math.random().toString(),
  91 + fenix: true
  92 +)
  93 +
  94 +Get.lazyPut<Controller>( () => Controller() )
  95 +```
  96 +
  97 +lazyPut'u kullanırken ayarlayabileceğiniz tüm seçenekler şunlardır:
  98 +```dart
  99 +Get.lazyPut<S>(
  100 + // zorunlu: sınıfınız ilk kez çağrıldığında yürütülecek bir yöntem
  101 + InstanceBuilderCallback builder,
  102 +
  103 + // isteğe bağlı: Get.put() ile aynı, aynı sınıfın birden çok farklı örneğini istediğinizde kullanılır
  104 + // unique olmalı
  105 + String tag,
  106 +
  107 + // isteğe bağlı: "Kalıcı" ile benzerdir, aradaki fark, instance şu durumlarda atılmasıdır.
  108 + // kullanılmıyor, ancak tekrar kullanılması gerektiğinde Get, instance yeniden oluşturacak
  109 + //bindings api'sindeki "SmartManagement.keepFactory" ile aynı
  110 + // varsayılan olarak false
  111 + bool fenix = false
  112 +
  113 +)
  114 +```
  115 +
  116 +### Get.putAsync
  117 +Eşzamansız bir instance kaydetmek istiyorsanız, `Get.putAsync` kullanabilirsiniz:
  118 +
  119 +```dart
  120 +Get.putAsync<SharedPreferences>(() async {
  121 + final prefs = await SharedPreferences.getInstance();
  122 + await prefs.setInt('counter', 12345);
  123 + return prefs;
  124 +});
  125 +
  126 +Get.putAsync<YourAsyncClass>( () async => await YourAsyncClass() )
  127 +```
  128 +
  129 +putAsync kullanırken ayarlayabileceğiniz tüm seçenekler şunlardır:
  130 +```dart
  131 +Get.putAsync<S>(
  132 +
  133 + // zorunlu: sınıfınızın instance'ını oluşturmak için yürütülecek bir asenkron metod
  134 + AsyncInstanceBuilderCallback<S> builder,
  135 +
  136 + //isteğe bağlı: Get.put() ile aynı, aynı sınıfın birden çok farklı örneğini istediğinizde kullanılır
  137 + // unique olmalı
  138 + String tag,
  139 +
  140 + // isteğe bağlı: Get.put() ile aynı, bu instance tüm uygulamada canlı tutmanız gerektiğinde kullanılır
  141 + // varsayılan olarak false
  142 + bool permanent = false
  143 +)
  144 +```
  145 +
  146 +### Get.create
  147 +
  148 +Bu zor. Bunun ne olduğuna ve diğeri arasındaki farklara ilişkin ayrıntılı bir açıklama, [Differences between methods:](#differences-between-methods) bölümünde bulunabilir.
  149 +
  150 +```dart
  151 +Get.Create<SomeClass>(() => SomeClass());
  152 +Get.Create<LoginController>(() => LoginController());
  153 +```
  154 +
  155 +Oluştururken ayarlayabileceğiniz tüm seçenekler şunlardır:
  156 +
  157 +```dart
  158 +Get.create<S>(
  159 + // gerekli: her seferinde "fabrikasyon" olacak bir sınıf döndüren bir işlev
  160 + // `Get.find()` çağrılır
  161 + // Örnek: Get.create<YourClass>(() => YourClass())
  162 + FcBuilderFunc<S> builder,
  163 +
  164 + // isteğe bağlı: tıpkı Get.put() gibi, ancak birden çok örneğe ihtiyacınız olduğunda kullanılır
  165 + // aynı sınıftan bir
  166 + // Her öğenin kendi denetleyicisine ihtiyaç duyduğu bir listeniz varsa kullanışlıdır
  167 + // benzersiz bir dize olması gerekir.
  168 + String name,
  169 +
  170 + // isteğe bağlı: tıpkı int`Get.put()` gibi,
  171 + // tüm uygulama boyunca canlı örnek. Fark Get.create'de
  172 + // kalıcı, varsayılan olarak doğrudur
  173 + bool permanent = true
  174 +```
  175 +
  176 +## Metodların/Sınıfların örneklerinin kullanılması
  177 +
  178 +Çok sayıda rotada gezindiğinizi ve kontrol cihazınızda geride bırakılan bir veriye ihtiyacınız olduğunu hayal edin, Sağlayıcı veya Get_it ile birleştirilmiş bir durum yöneticisine ihtiyacınız olacak, değil mi? Get ile değil. Controller için "find" seçeneğini sormanız yeterlidir, herhangi bir ek bağımlılığa ihtiyacınız yoktur:
  179 +
  180 +```dart
  181 +final controller = Get.find<Controller>();
  182 +// veya
  183 +Controller controller = Get.find();
  184 +
  185 +// Evet, sihir gibi görünüyor, Controller'ı(Denetleyicinizi) bulacak ve size teslim edecek.
  186 +// Instance edilmiş 1 milyon controller'a sahip olabilirsiniz, Get size her zaman doğru controller'ı verecektir.
  187 +```
  188 +
  189 +Ve sonra orada elde edilen controller ile verilerinizi kurtarabileceksiniz:
  190 +
  191 +```dart
  192 +Text(controller.textFromApi);
  193 +```
  194 +
  195 +Döndürülen değer normal bir sınıf olduğundan, istediğiniz her şeyi yapabilirsiniz:
  196 +```dart
  197 +int count = Get.find<SharedPreferences>().getInt('counter');
  198 +print(count); // out: 12345
  199 +```
  200 +
  201 +Get örneğini kaldırmak için:
  202 +
  203 +```dart
  204 +Get.delete<Controller>(); //genellikle bunu yapmanız gerekmez çünkü GetX kullanılmayan controller'ları(denetleyicileri) zaten siler
  205 +```
  206 +
  207 +## Alternatif bir instance tanımlama
  208 +
  209 +Şu anda eklenen bir örnek, `replace` veya `lazyReplace` yöntemi kullanılarak benzer veya genişletilmiş bir sınıf örneğiyle değiştirilebilir. Bu daha sonra özgün sınıf kullanılarak alınabilir.
  210 +
  211 +```dart
  212 +abstract class BaseClass {}
  213 +class ParentClass extends BaseClass {}
  214 +
  215 +class ChildClass extends ParentClass {
  216 + bool isChild = true;
  217 +}
  218 +
  219 +
  220 +Get.put<BaseClass>(ParentClass());
  221 +
  222 +Get.replace<BaseClass>(ChildClass());
  223 +
  224 +final instance = Get.find<BaseClass>();
  225 +print(instance is ChildClass); //true
  226 +
  227 +
  228 +class OtherClass extends BaseClass {}
  229 +Get.lazyReplace<BaseClass>(() => OtherClass());
  230 +
  231 +final instance = Get.find<BaseClass>();
  232 +print(instance is ChildClass); // false
  233 +print(instance is OtherClass); //true
  234 +```
  235 +
  236 +## Metodlar arasındaki farklılıklar
  237 +
  238 +İlk olarak Get.lazyPut'un `fenix`i ve diğer yöntemlerin `permanent`'larından bahsedelim.
  239 +
  240 +`permanent` ve `fenix` arasındaki temel fark, örneklerinizi nasıl depolamak istediğinizdir.
  241 +
  242 +Güçlendirme: Varsayılan olarak GetX, kullanımda değilken örnekleri siler.
  243 +Bunun anlamı: Ekran 1'de controller 1 varsa ve ekran 2'de controller 2 varsa ve ilk rotayı stackten kaldırırsanız (`Get.off()` veya `Get.offNamed()` kullanıyorsanız) controller(denetleyici) 1 kaybolur kullanımı silinecektir.
  244 +
  245 +Ancak `permanent:true` kullanmayı tercih etmek istiyorsanız, bu geçişte controller kaybolmaz - bu, tüm uygulama boyunca canlı tutmak istediğiniz hizmetler için çok yararlıdır.
  246 +
  247 +`fenix`ise ekran değişiklikleri arasında kaybetme endişesi duymadığınız ancak o hizmete ihtiyaç duyduğunuzda canlı olmasını beklediğiniz hizmetler içindir. Temel olarak, kullanılmayan controller/service/class elden çıkaracak, ancak ihtiyacınız olduğunda yeni bir örneği "küllerden yeniden yaratacaktır".
  248 +
  249 +Metodlar arasındaki farklarla devam edelim:
  250 +
  251 +- Get.put ve Get.putAsync, ikincisinin eşzamansız bir yöntem kullanması farkıyla aynı oluşturma sırasını takip eder: bu iki yöntem, örneği oluşturur ve başlatır. Bu, `permanent: false` ve `isSingleton: true` parametreleriyle `insert` dahili yöntemi kullanılarak doğrudan belleğe eklenir (bu isSingleton parametresinin tek amacı, "bağımlılık" bağımlılığını kullanıp kullanmayacağını söylemektir. veya `FcBuilderFunc` bağımlılığını kullanacaksa). Bundan sonra, bellekteki örnekleri hemen başlatan `Get.find()` çağrılır.
  252 +
  253 +
  254 +- Get.create: Adından da anlaşılacağı gibi, dependency'i (bağımlılığı) "create(oluşturacak)"! `Get.put()`a benzer şekilde, örneklemeye `insert` dahili yöntemini de çağırır. Ancak `permanent` doğru oldu ve`isSingleton` yanlış oldu (bağımlılığımızı "creating", bunun tek bir örnek olmasının bir yolu yok, bu yüzden yanlış). Ve `permanent: true` olduğu için, varsayılan olarak ekranlar arasında kaybetmeme avantajına sahibiz! Ayrıca `Get.find()` hemen çağrılmaz, çağrılacak ekranda kullanılmayı bekler. `permanent` parametresini kullanmak için bu şekilde yaratılmıştır, o zamandan beri, fark edilmeye değer `Get.create()`, örneğin bir bu liste için benzersiz bir örnek istiyorsanız - bu nedenle Get.create GetWidget ile birlikte kullanılmalıdır.
  255 +
  256 +- Get.lazyPut: Adından da anlaşılacağı gibi tembel bir işlemdir. Örnek yaratılır, ancak hemen kullanılmak üzere çağrılmaz, çağrılmayı bekler. Diğer yöntemlerin aksine burada `insert` denilmez. Bunun yerine, instance hafızanın başka bir bölümüne, örneğin yeniden oluşturulup oluşturulamayacağını söylemekle sorumlu bir kısma eklenir, buna "factory" diyelim. Daha sonra kullanılmak üzere bir şey yaratmak istersek, şu anda kullanılanlarla karıştırılmayacak. Ve işte burada `fenix` sihirleri devreye giriyor: `fenix: false` bırakmayı seçerseniz ve `smartManagement`ınız `keepFactory` değilse, o zaman `Get.find` kullanılırken örnek bellekteki yeri değiştirecektir. "factory"den ortak örnek bellek alanına. Bundan hemen sonra, varsayılan olarak "factory"den kaldırılır. Şimdi, `fenix: true` seçeneğini seçerseniz, örnek bu özel bölümde var olmaya devam eder, hatta gelecekte tekrar çağrılmak üzere ortak alana gider.
  257 +
  258 +## Bindings
  259 +
  260 +Bu paketin en büyük farklılıklarından biri, belki de route'ların, state manager'in(durum yöneticisinin) ve dependency manager(bağımlılık yöneticisinin) tam entegrasyonu olasılığıdır.
  261 +Stackten bir rota kaldırıldığında, onunla ilgili tüm controller'lar, değişkenler ve nesne örnekleri bellekten kaldırılır. Streams(Akışlar) veya timers(zamanlayıcılar) kullanıyorsanız, bunlar otomatik olarak kapatılır ve bunların hiçbiri için endişelenmenize gerek yoktur.
  262 +2.10 sürümünde Bindings API'sini tamamen uygulayın.
  263 +Artık init metodunu kullanmanıza gerek yok. İstemiyorsanız controller yazmanız bile gerekmez. Bunun için uygun yerde controller ve servislerinizi başlatabilirsiniz.
  264 +Binding sınıfı, state manager(durum yöneticisine) ve dependency manager(bağımlılık yöneticisine) giden rotaları "binding" ederken, dependency injection(bağımlılık enjeksiyonunu) ayıracak bir sınıftır.
  265 +Bu, belirli bir controller(denetleyici) kullanıldığında hangi ekranın görüntülenmekte olduğunu ve bunun nerede ve nasıl imha edileceğini bilmenizi sağlar.
  266 +Ayrıca Binding sınıfı, SmartManager yapılandırma kontrolüne sahip olmanızı sağlar. Stackten bir rota kaldırılırken veya onu kullanan pencere öğesi düzenlendiğinde veya hiçbirini yapmadığında düzenlenecek bağımlılıkları yapılandırabilirsiniz. Sizin için çalışan intelligent dependency management(akıllı bağımlılık yönetimine) sahip olacaksınız, ancak buna rağmen istediğiniz gibi yapılandırabilirsiniz.
  267 +
  268 +### Bindings class
  269 +
  270 +- Bir sınıf oluşturun ve Binding'i uygulayın
  271 +
  272 +```dart
  273 +class HomeBinding implements Bindings {}
  274 +```
  275 +
  276 +IDE'niz otomatik olarak sizden "dependencies(bağımlılıklar)" metodunu geçersiz kılmanızı isteyecektir ve sadece lambaya tıklamanız, metodu geçersiz kılmanız ve o rotada kullanacağınız tüm sınıfları eklemeniz yeterlidir:
  277 +
  278 +```dart
  279 +class HomeBinding implements Bindings {
  280 + @override
  281 + void dependencies() {
  282 + Get.lazyPut<HomeController>(() => HomeController());
  283 + Get.put<Service>(()=> Api());
  284 + }
  285 +}
  286 +
  287 +class DetailsBinding implements Bindings {
  288 + @override
  289 + void dependencies() {
  290 + Get.lazyPut<DetailsController>(() => DetailsController());
  291 + }
  292 +}
  293 +```
  294 +
  295 +Şimdi sadece rotanızı, route manager(rota yöneticisi), dependencies(bağımlılıklar) ve states(durumlar) arasında bağlantı kurmak için bu binding'i kullanacağınızı bildirmeniz gerekiyor.
  296 +
  297 +- Adlandırılmış yolları kullanma:
  298 +
  299 +```dart
  300 +getPages: [
  301 + GetPage(
  302 + name: '/',
  303 + page: () => HomeView(),
  304 + binding: HomeBinding(),
  305 + ),
  306 + GetPage(
  307 + name: '/details',
  308 + page: () => DetailsView(),
  309 + binding: DetailsBinding(),
  310 + ),
  311 +];
  312 +```
  313 +
  314 +- Normal yolları kullanma:
  315 +
  316 +```dart
  317 +Get.to(Home(), binding: HomeBinding());
  318 +Get.to(DetailsView(), binding: DetailsBinding())
  319 +```
  320 +
  321 +Orada, artık uygulamanızın bellek yönetimi konusunda endişelenmenize gerek yok, Get bunu sizin için yapacak.
  322 +
  323 +Bir rota çağrıldığında Binding sınıfı çağrılır, oluşturulacak tüm bağımlılıkları eklemek için GetMaterialApp'ınızda bir "initialBinding" oluşturabilirsiniz.
  324 +
  325 +```dart
  326 +GetMaterialApp(
  327 + initialBinding: SampleBind(),
  328 + home: Home(),
  329 +);
  330 +```
  331 +
  332 +### BindingsBuilder
  333 +
  334 +Binding oluşturmanın varsayılan yolu, Binding'leri uygulayan bir sınıf oluşturmaktır.
  335 +Ancak alternatif olarak, istediğiniz her şeyi somutlaştırmak için bir işlevi kullanabilmeniz için `BindingsBuilder` callback kullanabilirsiniz.
  336 +
  337 +Örnek:
  338 +
  339 +```dart
  340 +getPages: [
  341 + GetPage(
  342 + name: '/',
  343 + page: () => HomeView(),
  344 + binding: BindingsBuilder(() {
  345 + Get.lazyPut<ControllerX>(() => ControllerX());
  346 + Get.put<Service>(()=> Api());
  347 + }),
  348 + ),
  349 + GetPage(
  350 + name: '/details',
  351 + page: () => DetailsView(),
  352 + binding: BindingsBuilder(() {
  353 + Get.lazyPut<DetailsController>(() => DetailsController());
  354 + }),
  355 + ),
  356 +];
  357 +```
  358 +
  359 +Bu şekilde, her rota için bir Binding sınıfı oluşturmaktan kaçınarak bunu daha da basitleştirebilirsiniz.
  360 +
  361 +Her iki şekilde de gayet iyi çalışıyor ve zevkinize en uygun olanı kullanmanızı istiyoruz.
  362 +
  363 +### SmartManagement
  364 +
  365 +GetX, bir hata oluşsa ve onu kullanan bir pencere öğesi düzgün şekilde atılmamış olsa bile, varsayılan olarak kullanılmayan controller(denetleyicileri) bellekten atar.
  366 +Bu, `full` dependency management(bağımlılık yönetimi) modu olarak adlandırılan şeydir.
  367 +Ancak GetX'in sınıfların imhasını kontrol etme şeklini değiştirmek istiyorsanız, farklı davranışlar ayarlayabileceğiniz `SmartManagement` sınıfınız var.
  368 +
  369 +#### Nasıl değiştirilir?
  370 +
  371 +Bu yapılandırmayı (genellikle ihtiyacınız olmayan) şekilde değiştirmek istiyorsanız:
  372 +
  373 +```dart
  374 +void main () {
  375 + runApp(
  376 + GetMaterialApp(
  377 + smartManagement: SmartManagement.onlyBuilder //burada
  378 + home: Home(),
  379 + )
  380 + )
  381 +}
  382 +```
  383 +
  384 +#### SmartManagement.full
  385 +
  386 +Varsayılan olanıdır. Kullanılmayan ve kalıcı olarak ayarlanmamış sınıfları dispose edin. Çoğu durumda, bu yapılandırmayı el değmeden tutmak isteyeceksiniz. Eğer Get için yeniyseniz, bunu değiştirmeyin.
  387 +
  388 +#### SmartManagement.onlyBuilder
  389 +Bu seçenekle, yalnızca `init:` ile başlatılan veya `Get.lazyPut()` ile bir Binding'e yüklenen controller(denetleyiciler) dispose edilecektir.
  390 +
  391 +`Get.put()` veya `Get.putAsync()` veya başka bir yaklaşım kullanırsanız, SmartManagement bu bağımlılığı dışlamak için izinlere sahip olmayacaktır.
  392 +
  393 +Varsayılan davranışla, SmartManagement.onlyBuilder'ın aksine "Get.put" ile örneklenen widget'lar bile kaldırılacaktır.
  394 +
  395 +#### SmartManagement.keepFactory
  396 +
  397 +SmartManagement.full gibi, artık kullanılmadığında bağımlılıklarını kaldıracaktır. Ancak, factory'leri koruyacak, yani bu örneğe tekrar ihtiyacınız olursa dependency(bağımlılığı) yeniden yaratacaktır.
  398 +
  399 +### Nasıl bindings yapılır?
  400 +Bindings, başka bir ekrana gitmek için tıkladığınız anda oluşturulan geçici factory'ler oluşturur ve ekran değişirken animasyon gerçekleşir gerçekleşmez yok edilir.
  401 +Bu o kadar hızlı gerçekleşir ki analyzer onu kaydedemez bile.
  402 +Bu ekrana tekrar gittiğinizde, yeni bir geçici factory çağrılır, bu nedenle SmartManagement.keepFactory kullanmak yerine bu tercih edilir, ancak Bindings oluşturmak istemiyorsanız veya tüm bağımlılıklarınızı aynı Binding üzerinde tutmak istiyorsanız, mutlaka size yardımcı olacaktır.
  403 +Factory'ler çok az bellek kaplarlar, örnekleri tutmazlar, ancak istediğiniz sınıfın "shape" olan bir fonksiyona sahiptirler.
  404 +Bunun bellekte maliyeti çok düşüktür, ancak bu kitaplığın amacı, minimum kaynakları kullanarak mümkün olan maksimum performansı elde etmek olduğundan, Get factory bile varsayılan olarak kaldırır.
  405 +Hangisi sizin için daha uygunsa onu kullanın.
  406 +
  407 +## Notlar
  408 +
  409 +- Birden çok Bindings kullanıyorsanız SmartManagement.keepFactory KULLANMAYIN. Bindings olmadan veya GetMaterialApp'in initialBinding'inde bağlantılı tek bir Binding ile kullanılmak üzere tasarlanmıştır.
  410 +
  411 +- Bindings kullanmak tamamen isteğe bağlıdır, isterseniz belirli bir controller(denetleyiciyi) kullanan sınıflarda `Get.put()` ve `Get.find()` kullanabilirsiniz.
  412 +Ancak, Services veya başka bir abstract class ile çalışıyorsanız, daha iyi bir organizasyon için Bindings'i kullanmanızı öneririm.
  1 +- [Rota Yönetimi (Route Management)](#route-management)
  2 + - [Nasıl kullanılır?](#nasıl-kullanılır)
  3 + - [Adlandırılmış rotalar olmadan navigasyon](#adlandırılmış-rotalar-olmadan-navigasyon)
  4 + - [Adlandırılmış rotalarla navigasyon](#adlandırılmış-rotalarla-navigasyon)
  5 + - [Verileri adlandırılmış rotalara gönder](#verileri-adlandırılmış-rotalara-gönder)
  6 + - [Dinamik URL bağlantıları](#dinamik-url-bağlantıları)
  7 + - [Middleware](#middleware)
  8 + - [Context olmadan Navigasyon](#context-olmadan-navigasyon)
  9 + - [SnackBars](#snackbars)
  10 + - [Dialogs](#dialogs)
  11 + - [BottomSheets](#bottomsheets)
  12 + - [Nested Navigasyon](#nested-navigasyon)
  13 +
  14 +# Route Management
  15 +
  16 +Konu rota yönetimi olduğunda Getx için gereken her şeyin tam açıklaması budur.
  17 +
  18 +## Nasıl kullanılır?
  19 +
  20 +Bunu pubspec.yaml dosyanıza ekleyin:
  21 +
  22 +```yaml
  23 +dependencies:
  24 + get:
  25 +```
  26 +
  27 +Context olmadan routes/snackbars/dialogs/bottomsheets kullanacaksanız veya üst düzey Get API'lerini kullanacaksanız, `MaterialApp`'ınızdan önce `Get` eklemeniz, `GetMaterialApp`'a dönüştürmeniz ve keyfini çıkarmanız yeterlidir!
  28 +
  29 +```dart
  30 +GetMaterialApp( // Öncesi: MaterialApp(
  31 + home: MyHome(),
  32 +)
  33 +```
  34 +
  35 +## Adlandırılmış rotalar olmadan navigasyon
  36 +
  37 +Yeni bir ekrana gitmek için:
  38 +
  39 +```dart
  40 +Get.to(NextScreen());
  41 +```
  42 +
  43 +Snackbar'ları, Dialog'ları, Bottomsheet'leri veya normalde kapatacağınız herhangi bir şeyi kapatmak için `Navigator.pop(context);`
  44 +
  45 +```dart
  46 +Get.back();
  47 +```
  48 +
  49 +Bir sonraki ekrana gittikten sonra önceki ekrana geri dönme seçeneğinin olmaması için (SplashScreens, Login ekranlarında vb. kullanım için)
  50 +
  51 +```dart
  52 +Get.off(NextScreen());
  53 +```
  54 +
  55 +Bir sonraki ekrana gittikten sonra önceki tüm rotaları iptal etmek için (Alışveriş sepetlerinde, Anketlerde ve Testlerde kullanışlıdır)
  56 +
  57 +```dart
  58 +Get.offAll(NextScreen());
  59 +```
  60 +
  61 +Bir sonraki rotaya gitmek ve geri döner dönmez verileri almak veya güncellemek için:
  62 +
  63 +```dart
  64 +var data = await Get.to(Payment());
  65 +```
  66 +
  67 +diğer ekrandan önceki rota için bir veri gönderin:
  68 +
  69 +```dart
  70 +Get.back(result: 'success');
  71 +```
  72 +
  73 +Ve kullanın:
  74 +
  75 +Örn:
  76 +
  77 +```dart
  78 +if(data == 'success') madeAnything();
  79 +```
  80 +
  81 +Sözdizimimizi öğrenmek istemiyor musun? Navigator'ı (büyük harf) navigator (küçük harf) olarak değiştirin ve bağlam(context) kullanmak zorunda kalmadan standart navigasyonun tüm işlevlerine sahip olacaksınız.
  82 +Örnek:
  83 +
  84 +```dart
  85 +
  86 +// Varsayılan Flutter Navigator
  87 +Navigator.of(context).push(
  88 + context,
  89 + MaterialPageRoute(
  90 + builder: (BuildContext context) {
  91 + return HomePage();
  92 + },
  93 + ),
  94 +);
  95 +
  96 +// Bağlama(context) ihtiyaç duymadan Flutter sözdizimini(syntax) kullanın
  97 +navigator.push(
  98 + MaterialPageRoute(
  99 + builder: (_) {
  100 + return HomePage();
  101 + },
  102 + ),
  103 +);
  104 +
  105 +// Get syntax (Bu kullanım çok daha iyidir. Tabiki siz karşı çıkma hakkına sahipsiniz.)
  106 +Get.to(HomePage());
  107 +
  108 +
  109 +```
  110 +
  111 +### Adlandırılmış Rotalarla Navigasyon
  112 +
  113 +- NamedRoutes ile gezinmeyi tercih ederseniz, Get de bunu destekler.
  114 +
  115 +nextScreen'e gitmek için
  116 +
  117 +```dart
  118 +Get.toNamed("/NextScreen");
  119 +```
  120 +
  121 +Ağaçta ve önceki ekranda gezinmek için.
  122 +
  123 +```dart
  124 +Get.offNamed("/NextScreen");
  125 +```
  126 +
  127 +Ağaçta gezinmek ve önceki tüm ekranları kaldırmak için
  128 +
  129 +```dart
  130 +Get.offAllNamed("/NextScreen");
  131 +```
  132 +
  133 +Rotaları tanımlamak için `GetMaterialApp`'i kullanın:
  134 +
  135 +```dart
  136 +void main() {
  137 + runApp(
  138 + GetMaterialApp(
  139 + initialRoute: '/',
  140 + getPages: [
  141 + GetPage(name: '/', page: () => MyHomePage()),
  142 + GetPage(name: '/second', page: () => Second()),
  143 + GetPage(
  144 + name: '/third',
  145 + page: () => Third(),
  146 + transition: Transition.zoom
  147 + ),
  148 + ],
  149 + )
  150 + );
  151 +}
  152 +```
  153 +
  154 +Tanımsız rotalara navigasyonu yönetmek için (404 hatası), `GetMaterialApp`'de bir `unknownRoute` sayfası tanımlayabilirsiniz.
  155 +
  156 +```dart
  157 +void main() {
  158 + runApp(
  159 + GetMaterialApp(
  160 + unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()),
  161 + initialRoute: '/',
  162 + getPages: [
  163 + GetPage(name: '/', page: () => MyHomePage()),
  164 + GetPage(name: '/second', page: () => Second()),
  165 + ],
  166 + )
  167 + );
  168 +}
  169 +```
  170 +
  171 +### Verileri adlandırılmış Rotalara gönder
  172 +
  173 +
  174 +Sadece argümanlar için istediğinizi gönderin. Get, burada bir String, Map, List veya hatta bir Class örneği olsun, her şeyi kabul eder.
  175 +
  176 +```dart
  177 +Get.toNamed("/NextScreen", arguments: 'Get is the best');
  178 +```
  179 +
  180 +sınıfınızda(class) veya denetleyicinizde(controller):
  181 +
  182 +```dart
  183 +print(Get.arguments);
  184 +//print out: Get is the best
  185 +```
  186 +
  187 +### Dinamik URL bağlantıları
  188 +
  189 +Web'deki gibi gelişmiş dinamik url'ler sunun. Web geliştiricileri muhtemelen bu özelliği Flutter'da istemişlerdir ve büyük olasılıkla bir paketin bu özelliği vaat ettiğini ve bir URL'nin web'de bulunacağından tamamen farklı bir sözdizimi sunduğunu görmüşlerdir, ancak Get bunu da çözmektedir.
  190 +
  191 +```dart
  192 +Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
  193 +```
  194 +
  195 +controller/bloc/stateful/stateless Sınıfınıza:
  196 +
  197 +```dart
  198 +print(Get.parameters['id']);
  199 +// out: 354
  200 +print(Get.parameters['name']);
  201 +// out: Enzo
  202 +```
  203 +
  204 +Ayrıca Get ile Adlandırılmış Parametreleri kolayca alabilirsiniz:
  205 +
  206 +```dart
  207 +void main() {
  208 + runApp(
  209 + GetMaterialApp(
  210 + initialRoute: '/',
  211 + getPages: [
  212 + GetPage(
  213 + name: '/',
  214 + page: () => MyHomePage(),
  215 + ),
  216 + GetPage(
  217 + name: '/profile/',
  218 + page: () => MyProfile(),
  219 + ),
  220 + //Argümanlı rotalar için farklı bir sayfa ve argümansız başka bir sayfa tanımlayabilirsiniz, ancak bunun için yukarıdaki gibi argüman almayacak olan rotada '/' eğik çizgisini kullanmanız gerekir.
  221 + GetPage(
  222 + name: '/profile/:user',
  223 + page: () => UserProfile(),
  224 + ),
  225 + GetPage(
  226 + name: '/third',
  227 + page: () => Third(),
  228 + transition: Transition.cupertino
  229 + ),
  230 + ],
  231 + )
  232 + );
  233 +}
  234 +```
  235 +
  236 +Rota adına veri gönder
  237 +
  238 +```dart
  239 +Get.toNamed("/profile/34954");
  240 +```
  241 +
  242 +İkinci ekranda verileri parametreye göre alın
  243 +
  244 +```dart
  245 +print(Get.parameters['user']);
  246 +// out: 34954
  247 +```
  248 +
  249 +veya bunun gibi birden çok parametre gönderin
  250 +
  251 +```dart
  252 +Get.toNamed("/profile/34954?flag=true&country=italy");
  253 +```
  254 +veya
  255 +```dart
  256 +var parameters = <String, String>{"flag": "true","country": "italy",};
  257 +Get.toNamed("/profile/34954", parameters: parameters);
  258 +```
  259 +
  260 +İkinci ekranda, verileri genellikle olduğu gibi parametrelere göre alın
  261 +
  262 +```dart
  263 +print(Get.parameters['user']);
  264 +print(Get.parameters['flag']);
  265 +print(Get.parameters['country']);
  266 +// out: 34954 true italy
  267 +```
  268 +
  269 +
  270 +
  271 +Ve şimdi tek yapmanız gereken, herhangi bir bağlam(context) olmaksızın adlandırılmış rotalarınızda gezinmek için Get.toNamed()'i kullanmaktır (rotalarınızı doğrudan BLoC veya Controller sınıfınızdan çağırabilirsiniz) ve uygulamanız web'de derlendiğinde, rotalar url'de görünecek <3
  272 +
  273 +### Middleware
  274 +
  275 +Eylemleri tetiklemek için olayları almak dinlemek istiyorsanız routingCallback'i kullanabilirsiniz.
  276 +
  277 +```dart
  278 +GetMaterialApp(
  279 + routingCallback: (routing) {
  280 + if(routing.current == '/second'){
  281 + openAds();
  282 + }
  283 + }
  284 +)
  285 +```
  286 +
  287 +GetMaterialApp kullanmıyorsanız, Middleware gözlemcisini(observer) eklemek için manuel API'yi kullanabilirsiniz.
  288 +
  289 +```dart
  290 +void main() {
  291 + runApp(
  292 + MaterialApp(
  293 + onGenerateRoute: Router.generateRoute,
  294 + initialRoute: "/",
  295 + navigatorKey: Get.key,
  296 + navigatorObservers: [
  297 + GetObserver(MiddleWare.observer), // Burası !!!
  298 + ],
  299 + ),
  300 + );
  301 +}
  302 +```
  303 +
  304 +Bir MiddleWare sınıfı oluşturun
  305 +
  306 +```dart
  307 +class MiddleWare {
  308 + static observer(Routing routing) {
  309 + /// Her ekranda rotalar, snackbarlar, diyaloglar ve bottomsheetleri ek olarak dinleyebilirsiniz.
  310 + ///Bu 3 olaydan herhangi birini doğrudan buraya girmeniz gerekiyorsa,
  311 + ///Yapmaya çalıştığınızdan daha fazla olayın olduğunu != kullanarak belirtmelisiniz.
  312 + if (routing.current == '/second' && !routing.isSnackbar) {
  313 + Get.snackbar("Hi", "You are on second route");
  314 + } else if (routing.current =='/third'){
  315 + print('last route called');
  316 + }
  317 + }
  318 +}
  319 +```
  320 +
  321 +Şimdi, Get on kodunu kullanın:
  322 +
  323 +```dart
  324 +class First extends StatelessWidget {
  325 + @override
  326 + Widget build(BuildContext context) {
  327 + return Scaffold(
  328 + appBar: AppBar(
  329 + leading: IconButton(
  330 + icon: Icon(Icons.add),
  331 + onPressed: () {
  332 + Get.snackbar("hi", "i am a modern snackbar");
  333 + },
  334 + ),
  335 + title: Text('First Route'),
  336 + ),
  337 + body: Center(
  338 + child: ElevatedButton(
  339 + child: Text('Open route'),
  340 + onPressed: () {
  341 + Get.toNamed("/second");
  342 + },
  343 + ),
  344 + ),
  345 + );
  346 + }
  347 +}
  348 +
  349 +class Second extends StatelessWidget {
  350 + @override
  351 + Widget build(BuildContext context) {
  352 + return Scaffold(
  353 + appBar: AppBar(
  354 + leading: IconButton(
  355 + icon: Icon(Icons.add),
  356 + onPressed: () {
  357 + Get.snackbar("hi", "i am a modern snackbar");
  358 + },
  359 + ),
  360 + title: Text('second Route'),
  361 + ),
  362 + body: Center(
  363 + child: ElevatedButton(
  364 + child: Text('Open route'),
  365 + onPressed: () {
  366 + Get.toNamed("/third");
  367 + },
  368 + ),
  369 + ),
  370 + );
  371 + }
  372 +}
  373 +
  374 +class Third extends StatelessWidget {
  375 + @override
  376 + Widget build(BuildContext context) {
  377 + return Scaffold(
  378 + appBar: AppBar(
  379 + title: Text("Third Route"),
  380 + ),
  381 + body: Center(
  382 + child: ElevatedButton(
  383 + onPressed: () {
  384 + Get.back();
  385 + },
  386 + child: Text('Go back!'),
  387 + ),
  388 + ),
  389 + );
  390 + }
  391 +}
  392 +```
  393 +
  394 +## Context olmadan Navigasyon
  395 +
  396 +### SnackBars
  397 +
  398 +Flutter ile basit bir SnackBar'a sahip olmak için Scaffold bağlamını(context) almalısınız veya Scaffold'unuza bağlı bir GlobalKey kullanmalısınız.
  399 +
  400 +```dart
  401 +final snackBar = SnackBar(
  402 + content: Text('Hi!'),
  403 + action: SnackBarAction(
  404 + label: 'I am a old and ugly snackbar :(',
  405 + onPressed: (){}
  406 + ),
  407 +);
  408 +// Widget ağacında Scaffold'u bulun ve kullanın
  409 +// bir SnackBar göstermek için.
  410 +Scaffold.of(context).showSnackBar(snackBar);
  411 +```
  412 +
  413 +Get ile:
  414 +
  415 +```dart
  416 +Get.snackbar('Hi', 'i am a modern snackbar');
  417 +```
  418 +
  419 +Get ile, Yapmanız gereken tek şey kodunuzun herhangi bir yerinden Get.snackbar'ınızı aramak veya onu istediğiniz gibi özelleştirmek!
  420 +
  421 +```dart
  422 +Get.snackbar(
  423 + "Hey i'm a Get SnackBar!", // title
  424 + "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
  425 + icon: Icon(Icons.alarm),
  426 + shouldIconPulse: true,
  427 + onTap:(){},
  428 + barBlur: 20,
  429 + isDismissible: true,
  430 + duration: Duration(seconds: 3),
  431 +);
  432 +
  433 +
  434 + ////////// ALL FEATURES //////////
  435 + // Color colorText,
  436 + // Duration duration,
  437 + // SnackPosition snackPosition,
  438 + // Widget titleText,
  439 + // Widget messageText,
  440 + // bool instantInit,
  441 + // Widget icon,
  442 + // bool shouldIconPulse,
  443 + // double maxWidth,
  444 + // EdgeInsets margin,
  445 + // EdgeInsets padding,
  446 + // double borderRadius,
  447 + // Color borderColor,
  448 + // double borderWidth,
  449 + // Color backgroundColor,
  450 + // Color leftBarIndicatorColor,
  451 + // List<BoxShadow> boxShadows,
  452 + // Gradient backgroundGradient,
  453 + // TextButton mainButton,
  454 + // OnTap onTap,
  455 + // bool isDismissible,
  456 + // bool showProgressIndicator,
  457 + // AnimationController progressIndicatorController,
  458 + // Color progressIndicatorBackgroundColor,
  459 + // Animation<Color> progressIndicatorValueColor,
  460 + // SnackStyle snackStyle,
  461 + // Curve forwardAnimationCurve,
  462 + // Curve reverseAnimationCurve,
  463 + // Duration animationDuration,
  464 + // double barBlur,
  465 + // double overlayBlur,
  466 + // Color overlayColor,
  467 + // Form userInputForm
  468 + ///////////////////////////////////
  469 +```
  470 +
  471 +Geleneksel snackbar'ı tercih ediyorsanız veya yalnızca bir satır eklemek de dahil olmak üzere sıfırdan özelleştirmek istiyorsanız (Get.snackbar zorunlu bir başlık ve mesaj kullanır),
  472 +Get.snackbar'ın üzerine inşa edildiği RAW API'sini sağlayan `Get.rawSnackbar();` kullanabilirsiniz.
  473 +
  474 +### Dialogs
  475 +
  476 +Dialog'u açmak için:
  477 +
  478 +```dart
  479 +Get.dialog(YourDialogWidget());
  480 +```
  481 +
  482 +Varsayılan dialog açmak için:
  483 +
  484 +```dart
  485 +Get.defaultDialog(
  486 + onConfirm: () => print("Ok"),
  487 + middleText: "Dialog made in 3 lines of code"
  488 +);
  489 +```
  490 +
  491 +showGeneralDialog yerine Get.generalDialog'u da kullanabilirsiniz.
  492 +
  493 +Cupertinos dahil olmak üzere tüm diğer Flutter Dialog widget'ları için bağlam(context) yerine Get.overlayContext'i kullanabilir ve kodunuzun herhangi bir yerinde açabilirsiniz.
  494 +Overlay kullanmayan widget'lar için Get.context'i kullanabilirsiniz.
  495 +Bu iki bağlam(context), inheritedWidget'ın bir gezinme bağlamı(context) olmadan kullanıldığı durumlar dışında, kullanıcı arayüzünüzün bağlamını(context) değiştirmek için vakaların %99'unda çalışacaktır.
  496 +
  497 +### BottomSheets
  498 +
  499 +Get.bottomSheet, showModalBottomSheet gibidir, ancak bağlama(context) ihtiyaç duymaz.
  500 +
  501 +```dart
  502 +Get.bottomSheet(
  503 + Container(
  504 + child: Wrap(
  505 + children: <Widget>[
  506 + ListTile(
  507 + leading: Icon(Icons.music_note),
  508 + title: Text('Music'),
  509 + onTap: () {}
  510 + ),
  511 + ListTile(
  512 + leading: Icon(Icons.videocam),
  513 + title: Text('Video'),
  514 + onTap: () {},
  515 + ),
  516 + ],
  517 + ),
  518 + )
  519 +);
  520 +```
  521 +
  522 +## Nested Navigasyon
  523 +
  524 +Flutter'ın iç içe gezinmesini daha da kolaylaştırın.
  525 +İçeriğe ihtiyacınız yoktur ve navigasyon yığınınızı kimliğe(ID) göre bulacaksınız.
  526 +
  527 +- NOT: Paralel gezinme yığınları oluşturmak tehlikeli olabilir. İdeal olan, NestedNavigators'ı kullanmamak veya idareli kullanmaktır. Projeniz gerektiriyorsa, devam edin, ancak bellekte birden çok gezinme yığınını tutmanın RAM tüketimi için iyi bir fikir olmayabileceğini unutmayın.
  528 +
  529 +Bakın ne kadar basit:
  530 +
  531 +```dart
  532 +Navigator(
  533 + key: Get.nestedKey(1), // index göre anahtar oluşturma
  534 + initialRoute: '/',
  535 + onGenerateRoute: (settings) {
  536 + if (settings.name == '/') {
  537 + return GetPageRoute(
  538 + page: () => Scaffold(
  539 + appBar: AppBar(
  540 + title: Text("Main"),
  541 + ),
  542 + body: Center(
  543 + child: TextButton(
  544 + color: Colors.blue,
  545 + onPressed: () {
  546 + Get.toNamed('/second', id:1); // indexe göre iç içe geçmiş rotanıza göre gezinin
  547 + },
  548 + child: Text("Go to second"),
  549 + ),
  550 + ),
  551 + ),
  552 + );
  553 + } else if (settings.name == '/second') {
  554 + return GetPageRoute(
  555 + page: () => Center(
  556 + child: Scaffold(
  557 + appBar: AppBar(
  558 + title: Text("Main"),
  559 + ),
  560 + body: Center(
  561 + child: Text("second")
  562 + ),
  563 + ),
  564 + ),
  565 + );
  566 + }
  567 + }
  568 +),
  569 +```
  1 +* [State Management](#state-management)
  2 + + [Reactive State Manager](#reactive-state-manager)
  3 + - [Avantajlar](#avantajlar)
  4 + - [Maksimum Performans:](#maksimum-performans)
  5 + - [Reaktif bir değişken bildirmek](#reaktif-bir-değişken-bildirmek)
  6 + - [Reaktif bir state'e sahip olmak kolaydır.](#reaktif-bir-state'e-sahip-olmak-kolaydır)
  7 + - [Görünümdeki değerleri kullanmak](#görünümdeki-değerleri-kullanmak)
  8 + - [Yeniden oluşturulacak koşullar](#yeniden-oluşturulacak-koşullar)
  9 + - [Nerede .obs kullanılabilir](#nerede-obs-kullanılabilir)
  10 + - [Listeler hakkında not](#listeler-hakkında-not)
  11 + - [Neden .value kullanmak zorundayım?](#neden-value-kullanmak-zorundayım?)
  12 + - [Obx()](#obx)
  13 + - [Çalışanlar](#Çalışanlar)
  14 + + [Simple State Manager](#simple-state-manager)
  15 + - [Avantajlar](#avantajlar-1)
  16 + - [Kullanımı](#kullanımı)
  17 + - [Controller'lar nasıl çalışır](#controller'lar-nasıl-çalışır)
  18 + - [Artık StatefulWidget'lara ihtiyacınız olmayacak](#artık-statefulwidget'lara-ihtiyacınız-olmayacak)
  19 + - [Neden var](#neden-var)
  20 + - [Kullanmanın diğer yolları](#kullanmanın-diğer-yolları)
  21 + - [Unique IDs-Benzersiz Kimlikler](#unique-ids-benzersiz-kimlikler)
  22 + + [İki state managers ile Mixing](#İki-state-managers-ile-mixing)
  23 + + [GetBuilder vs GetX vs Obx vs MixinBuilder](#getbuilder-vs-getx-vs-obx-vs-mixinbuilder)
  24 +
  25 +# State Management
  26 +
  27 +GetX, diğer State Management'ler (Durum Yöneticileri) gibi Streams veya ChangeNotifier kullanmaz. Niye? GetX ile android, iOS, web, linux, macos ve linux için uygulamalar oluşturmaya ek olarak, Flutter/GetX ile aynı syntax(sözdizimine) sahip server(sunucu) uygulamaları oluşturabilirsiniz. Yanıt süresini iyileştirmek ve RAM tüketimini azaltmak için düşük işletim maliyetiyle çok fazla performans sunan düşük gecikmeli çözümler olan GetValue ve GetStream'i oluşturduk. State Management (Durum Yönetimi) de dahil olmak üzere tüm kaynaklarımızı oluşturmak için bu temeli kullanıyoruz.
  28 +
  29 +* _Complexity_ (Karmaşıklık): Bazı state management'ler karmaşıktır ve çok fazla ortak özelliği vardır. GetX ile her olay için bir sınıf tanımlamanız gerekmez, kod son derece temiz ve nettir ve daha az yazarak çok daha fazlasını yaparsınız. Pek çok insan bu konu yüzünden Flutter'dan vazgeçti ve şimdi nihayet durumları yönetmek için basit bir çözüme sahipler.
  30 +* _No code generators_ (Kod Oluşturucu Yok): Geliştirme zamanınızın yarısını uygulama mantığınızı yazmaya harcarsınız. Bazı state management'ler, minimum düzeyde okunabilir koda sahip olmak için kod oluşturuculara güvenir. Bir değişkeni değiştirmek ve build_runner'ı çalıştırmak verimsiz olabilir ve genellikle flutter clean'den sonraki bekleme süresi uzun olur ve çok fazla kahve içmeniz gerekir.
  31 +
  32 +GetX ile her şey reaktiftir ve hiçbir şey kod oluşturuculara bağlı değildir, bu da geliştirmenizin tüm yönlerinde üretkenliğinizi artırır.
  33 +
  34 +* _It does not depend on context(Context'e bağlı değil)_: Muhtemelen görünümünüzün context'ini (bağlam) bir denetleyiciye göndermeniz gerekiyordu, bu da görünümün iş mantığınızla bağlantısını yüksek hale getirdi. Muhtemelen context'i (bağlamı) olmayan bir yer için bir bağımlılık kullanmak zorunda kaldınız ve context'i(bağlamı) çeşitli sınıflar ve fonksiyonlardan geçirmek zorunda kaldınız.Bu sadece GetX ile mevcut değil. Controller'larınıza (Denetleyicilerinize) , controller'larınızın(denetleyicilerinizin) içinden herhangi bir context (bağlam) olmadan erişebilirsiniz. Kelimenin tam anlamıyla hiçbir şey için context'i(bağlamı) parametreye göre göndermeniz gerekmez.
  35 +* _Granular control(Parçacıklı Kontrol)_: Çoğu state management(durum yöneticisi) ChangeNotifier'ı temel alır. ChangeNotifier, notifyListeners çağrıldığında kendisine bağlı olan tüm widget'ları bilgilendirecektir. Bir ekranda ChangeNotifier sınıfınızın bir değişkenine sahip 40 widget'ınız varsa, birini güncellediğinizde hepsi yeniden oluşturulacaktır.
  36 +
  37 +GetX ile iç içe geçmiş widget'lara bile saygı duyulur. Obx listview'inizi izliyorsa ve diğeri ListView içinde bir onay kutusu izliyorsa, CheckBox değerini değiştirirken yalnızca o onay kutusu güncellenir, Liste değerini değiştirirken yalnızca ListView güncellenir.
  38 +
  39 +* _It only reconstructs if its variable REALLY changes (Değişken değişirse GERÇEKTEN yeniden yapılandırır)_: GetX akış kontrolüne sahiptir, yani 'Paola' ile bir text(metin) görüntülerseniz, (observable)gözlemlenebilir değişkeni tekrar 'Paola' olarak değiştirirseniz, widget yeniden yapılandırılmayacaktır. Çünkü GetX, 'Paola'nın' zaten text'de(metinde) görüntülendiğini ve gereksiz rekonstrüksiyonlar yapmayacağını biliyor.
  40 +
  41 +Mevcut state management'lerin(durum yöneticilerin) çoğu (hepsi değilse de) ekranda yeniden oluşturulur.
  42 +
  43 +## Reactive State Manager
  44 +
  45 +Reaktif programlama birçok insanı yabancılaştırabilir çünkü karmaşık olduğu söylenir. GetX reaktif programlamayı oldukça basit bir şeye dönüştürür:
  46 +
  47 +* Stream Controller oluşturmanıza gerek yoktur.
  48 +* Her değişken için bir StreamBuilder oluşturmanız gerekmez.
  49 +* Her state(durum) için bir sınıf oluşturmanız gerekmeyecektir.
  50 +* Bir initial value(başlangıç değeri) için bir get oluşturmanız gerekmeyecektir.
  51 +
  52 +Get ile reaktif programlama, Setstate'i kullanmak kadar kolaydır.
  53 +
  54 +Bir ad değişkeniniz olduğunu ve her değiştirdiğinizde onu kullanan tüm widget'ların otomatik olarak değiştirilmesini istediğinizi düşünelim.
  55 +
  56 +Bu sizin count(sayım) değişkeninizdir:
  57 +
  58 +``` dart
  59 +var name = 'Jonatas Borges';
  60 +```
  61 +
  62 +Observable hale getirmek için, sonuna ".obs" eklemeniz gerekir:
  63 +
  64 +``` dart
  65 +var name = 'Jonatas Borges'.obs;
  66 +```
  67 +
  68 +Hepsi bu. *Bu kadar basit* bir şey.
  69 +
  70 +Şu andan itibaren, bu reaktif-".obs"(ervables) değişkenlerine _Rx_ adını verebiliriz.
  71 +
  72 +Başlık altında ne yaptık? `String` lerin bir `Stream` oluşturduk, `"Jonatas Borges"` initial value'sunu(başlangıç değerini) atadık, `"Jonatas Borges"` kullanan tüm widget'lara artık bu değişkene "ait olduklarını" bildirdik ve _Rx_ değeri değiştiğinde de değişmeleri gerekecek.
  73 +
  74 +Bu, Dart'ın yetenekleri sayesinde **GetX'in büyüsüdür**.
  75 +
  76 +Ancak, bildiğimiz gibi, bir `Widget` yalnızca bir işlevin içindeyse değiştirilebilir, çünkü statik sınıflar "otomatik değiştirme" gücüne sahip değildir.
  77 +
  78 +Bir `StreamBuilder` oluşturmanız, değişiklikleri dinlemek için bu değişkene abone olmanız ve aynı kapsamdaki birkaç değişkeni değiştirmek istiyorsanız, iç içe geçmiş `StreamBuilder` bir "kaskad" oluşturmanız gerekir, değil mi?
  79 +
  80 +Hayır, bir `StreamBuilder`a ihtiyacınız yok, ancak statik sınıflar konusunda haklısınız.
  81 +
  82 +Pekala, görünüşe göre, belirli bir Widget'ı değiştirmek istediğimizde genellikle çok fazla ortak bilgimiz olur, bu Flutter yoludur.
  83 +**GetX** ile bu ortak kod kodunu da unutabilirsiniz.
  84 +
  85 +`StreamBuilder( … )` ? `initialValue: …` ? `builder: …` ? Hayır, bu değişkeni bir `Obx()` Widget'ına yerleştirmeniz yeterlidir.
  86 +
  87 +``` dart
  88 +Obx (() => Text (controller.name));
  89 +```
  90 +
  91 +_Ezberlemek için neye ihtiyacın var?_Sadece `Obx(() =>` .
  92 +
  93 +Bu Widget'ı bir ok işlevinden bir `Obx()` (_Rx_'in "Observable") içine geçiriyorsunuz.
  94 +
  95 +`Obx` oldukça akıllıdır ve yalnızca `controller.name`nin değeri değiştiğinde değişecektir.
  96 +
  97 +`name`, `"John"` ise ve onu `"John"` ( `name.value = "John"` ) olarak değiştirirseniz, öncekiyle aynı `değer` olduğundan, ekranda hiçbir şey değişmeyecektir, ve 'Obx' , kaynakları kurtarmak için yeni değeri yok sayar ve Widget'ı yeniden oluşturmaz. **Harika değil mi?**
  98 +
  99 +> Peki ya bir `Obx` içinde 5 _Rx_ (observable) değişkenim varsa?
  100 +
  101 +Yalnızca **herhangi biri** değiştiğinde güncellenecektir.
  102 +
  103 +> Ve bir sınıfta 30 değişkenim varsa, birini güncellediğimde, o sınıftaki değişkenlerin **tümünü** günceller mi?
  104 +
  105 +Hayır, sadece bu _Rx_ değişkenini kullanan **belirli Widget**.
  106 +
  107 +Bu nedenle, **GetX** yalnızca _Rx_ değişkeni değerini değiştirdiğinde ekranı günceller.
  108 +
  109 +```
  110 +
  111 +final isOpen = false.obs;
  112 +
  113 +// NOTHING will happen... same value.
  114 +void onButtonTap() => isOpen.value=false;
  115 +```
  116 +
  117 +### Avantajlar
  118 +
  119 +**GetX()**, güncellenen değişkenler üzerinde **ayrıntılı** kontrole ihtiyacınız olduğunda size yardımcı olur.
  120 +
  121 +Bir eylem gerçekleştirdiğinizde tüm değişkenleriniz değiştirileceğinden `unique IDs(benzersiz kimliklere)` ihtiyacınız yoksa, `GetBuilder`ı kullanın,
  122 +çünkü Simple State Updater(Basit Durum Güncelleyicisi)'dir (`setState ()` gibi bloklar halinde), sadece birkaç kod satırında yapılır.
  123 +En az CPU etkisine sahip olmak ve sadece tek bir amacı (_State_ rebuild) yerine getirmek ve mümkün olan en az kaynağı harcamak için basitleştirildi.
  124 +
  125 +**Güçlü** bir State Management (Durum Yöneticisi)'e ihtiyacınız varsa, **GetX** ile yanlış yapmış olamazsınız.
  126 +
  127 +Değişkenlerle çalışmaz, ancak __flows__, içindeki her şey başlık altındaki `Streams`dır.
  128 +
  129 +
  130 +_rxDart_ ile birlikte kullanabilirsiniz, çünkü her şey `Streams`,
  131 +her "_Rx_variable"ın 'event(olayını)' dinleyebilirsiniz,
  132 +çünkü içindeki her şey `Streams`'dir.
  133 +
  134 +Kelimenin tam anlamıyla bir _BLoC_ yaklaşımıdır, _MobX_'den daha kolaydır ve kod oluşturucuları veya süslemeleri yoktur.
  135 +**Herhangi bir şeyi** yalnızca bir `.obs` ile _"Observable"_ hale getirebilirsiniz.
  136 +
  137 +### Maksimum Performans:
  138 +
  139 +State Management (Durum Yöneticisinin)'in değiştiğinden emin olmak için akıllı bir algoritmaya sahip olmanın yanı sıra **GetX** comparators kullanır.
  140 +
  141 +Uygulamanızda herhangi bir hatayla karşılaşırsanız ve yinelenen bir State(durum) değişikliği gönderirseniz,
  142 +**GetX** çökmemesini sağlayacaktır.
  143 +
  144 +**GetX** ile State(Durum) yalnızca `value(değer)` değişirse değişir.
  145 +Bu, **GetX** ile mobx_'den _ `computed` kullanımı arasındaki temel farktır.
  146 +İki defa __observable__ 'da bir değişiklik yapıldığında; o _observable_ dinleyicisi de değişecektir.
  147 +
  148 +
  149 +**GetX** ile, iki değişkeni birleştirirseniz, `GetX()` (`Observer()`a benzer) yalnızca gerçek bir State(Durum) değişikliği gerektiriyorsa yeniden oluşturacaktır.
  150 +
  151 +### Reaktif bir değişken bildirmek
  152 +
  153 +Bir değişkeni "observable" hale getirmenin 3 yolu vardır.
  154 +
  155 +1 - Birincisi **`Rx{Type}`** kullanmak.
  156 +
  157 +``` dart
  158 +// initial value önerilir, zorunlu değildir.
  159 +final name = RxString('');
  160 +final isLogged = RxBool(false);
  161 +final count = RxInt(0);
  162 +final balance = RxDouble(0.0);
  163 +final items = RxList<String>([]);
  164 +final myMap = RxMap<String, int>({});
  165 +```
  166 +
  167 +2 - İkincisi, **`Rx`** kullanmak ve Darts Generics, `Rx<Type>` kullanmaktır.
  168 +
  169 +``` dart
  170 +final name = Rx<String>('');
  171 +final isLogged = Rx<Bool>(false);
  172 +final count = Rx<Int>(0);
  173 +final balance = Rx<Double>(0.0);
  174 +final number = Rx<Num>(0);
  175 +final items = Rx<List<String>>([]);
  176 +final myMap = Rx<Map<String, int>>({});
  177 +
  178 +// Custom classes - herhangi bir sınıf olabilir
  179 +final user = Rx<User>();
  180 +```
  181 +
  182 +3 - Üçüncü, daha pratik, daha kolay ve tercih edilen yaklaşım,`value`'ya bir **`.obs`** ekleyin:
  183 +
  184 +``` dart
  185 +final name = ''.obs;
  186 +final isLogged = false.obs;
  187 +final count = 0.obs;
  188 +final balance = 0.0.obs;
  189 +final number = 0.obs;
  190 +final items = <String>[].obs;
  191 +final myMap = <String, int>{}.obs;
  192 +
  193 +// Custom classes - herhangi bir sınıf olabilir
  194 +final user = User().obs;
  195 +```
  196 +
  197 +##### Reaktif bir state'e sahip olmak kolaydır.
  198 +
  199 +Bildiğimiz gibi, _Dart_ şimdi _null safety_ doğru gidiyor.
  200 +Şu andan itibaren hazırlıklı olmak için, _Rx_ değişkenlerinizi her zaman bir **initial value** ile başlatmalısınız.
  201 +
  202 +> Bir değişkeni **GetX** ile _observable_ + _initial value_ değerine dönüştürmek en basit ve pratik yaklaşımdır.
  203 +
  204 +Kelimenin tam anlamıyla bir değişkeninizin sonuna bir " `.obs` " ekleyeceksiniz, ve **bu kadar**. Şimdi onu gözlemlenebilir hale getirdiniz,
  205 +ve onun `.value(değer)`'i, _initial value_ olacaktır.
  206 +
  207 +### Görünümdeki değerleri kullanmak
  208 +
  209 +``` dart
  210 +// controller dosyası
  211 +final count1 = 0.obs;
  212 +final count2 = 0.obs;
  213 +int get sum => count1.value + count2.value;
  214 +```
  215 +
  216 +``` dart
  217 +// view dosyası
  218 +GetX<Controller>(
  219 + builder: (controller) {
  220 + print("count 1 rebuild");
  221 + return Text('${controller.count1.value}');
  222 + },
  223 +),
  224 +GetX<Controller>(
  225 + builder: (controller) {
  226 + print("count 2 rebuild");
  227 + return Text('${controller.count2.value}');
  228 + },
  229 +),
  230 +GetX<Controller>(
  231 + builder: (controller) {
  232 + print("count 3 rebuild");
  233 + return Text('${controller.sum}');
  234 + },
  235 +),
  236 +```
  237 +
  238 +`count1.value++` değerini artırırsak, şunu yazdırır:
  239 +
  240 +* `count 1 rebuild`
  241 +
  242 +* `count 3 rebuild`
  243 +
  244 +`count1`, `1` değerine sahip olduğundan ve `1 + 0 = 1` olduğundan, `toplam` değeri değiştirilir.
  245 +
  246 +`count2.value++` değerini değiştirirsek, şunu yazdırır:
  247 +
  248 +* `count 2 rebuild`
  249 +
  250 +* `count 3 rebuild`
  251 +
  252 +çünkü `count2.value` değişti ve `sum`un sonucu şimdi `2` oldu.
  253 +
  254 +* NOT: Varsayılan olarak, ilk etkinlik aynı `value` olsa bile widget'ı yeniden oluşturacaktır.
  255 +
  256 +Bu durum boolean değişkenlerinde de mevcuttur.
  257 +
  258 +Bunu yaptığınızı hayal edin:
  259 +
  260 +``` dart
  261 +var isLogged = false.obs;
  262 +```
  263 +
  264 +Ardından, bir kullanıcının `ever` içinde bir olayı tetiklemek için `isLogged` olup olmadığını kontrol ettiniz.
  265 +
  266 +``` dart
  267 +@override
  268 +onInit() async {
  269 + ever(isLogged, fireRoute);
  270 + isLogged.value = await Preferences.hasToken();
  271 +}
  272 +
  273 +fireRoute(logged) {
  274 + if (logged) {
  275 + Get.off(Home());
  276 + } else {
  277 + Get.off(Login());
  278 + }
  279 +}
  280 +```
  281 +
  282 +
  283 +`hasToken` `false` olsaydı, `isLogged`da herhangi bir değişiklik olmazdı, bu nedenle `ever()` asla çağrılmazdı.
  284 +Bu tür davranışlardan kaçınmak için, bir _observable_ öğesindeki ilk değişiklik her zaman bir olayı tetikleyecektir,
  285 +aynı `.value` değerini içerse bile.
  286 +
  287 +İsterseniz bu davranışı kullanarak kaldırabilirsiniz:
  288 + `isLogged.firstRebuild = false;`
  289 +
  290 +### Yeniden oluşturulacak koşullar
  291 +
  292 +Ek olarak, Get gelişmiş durum kontrolü sağlar. Bir olayı (listeye nesne ekleme gibi) belirli bir koşulda koşullandırabilirsiniz.
  293 +
  294 +``` dart
  295 +// İlk parametre: koşul, true veya false döndürmelidir.
  296 +// İkinci parametre: koşul doğruysa yeni değer uygulanacaktır.
  297 +list.addIf(item < limit, item);
  298 +```
  299 +
  300 +Süslemesiz, kod oluşturucusuz, komplikasyonsuz :smile:
  301 +
  302 +Flutter'ın sayaç uygulamasını biliyor musunuz? Controller sınıfınız şöyle görünebilir:
  303 +
  304 +``` dart
  305 +class CountController extends GetxController {
  306 + final count = 0.obs;
  307 +}
  308 +```
  309 +
  310 +Basit bir şekilde:
  311 +
  312 +``` dart
  313 +controller.count.value++
  314 +```
  315 +
  316 +Kullanıcı arabiriminizdeki sayaç değişkenini nerede depolandığına bakılmaksızın güncelleştirebilirsiniz.
  317 +
  318 +### Nerede .obs kullanılabilir
  319 +
  320 +Obs üzerindeki her şeyi dönüştürebilirsiniz. İşte bunu yapmanın iki yolu:
  321 +
  322 +* Sınıf değerlerinizi obs'ye dönüştürebilirsiniz
  323 +
  324 +``` dart
  325 +class RxUser {
  326 + final name = "Camila".obs;
  327 + final age = 18.obs;
  328 +}
  329 +```
  330 +
  331 +* veya tüm sınıfı observable hale getirebilirsiniz.
  332 +
  333 +``` dart
  334 +class User {
  335 + User({String name, int age});
  336 + var name;
  337 + var age;
  338 +}
  339 +
  340 +// örnek:
  341 +final user = User(name: "Camila", age: 18).obs;
  342 +```
  343 +
  344 +### Listeler hakkında not
  345 +
  346 +Listeler, içindeki nesneler gibi tamamen gözlemlenebilir. Bu şekilde, bir listeye bir değer eklerseniz, onu kullanan widget'ları otomatik olarak yeniden oluşturur.
  347 +
  348 +Ayrıca listelerde ".value" kullanmanıza gerek yok, harika dart api'ları bunu kaldırmamıza izin verdi.
  349 +Ne yazık ki, String ve int gibi ilkel türler genişletilemez, bu da kullanımını sağlar. Değer zorunludur, ancak bunlar için get ve setter'larla çalışıyorsanız bu bir sorun olmayacaktır.
  350 +
  351 +``` dart
  352 +// On the controller
  353 +final String title = 'User Info:'.obs
  354 +final list = List<User>().obs;
  355 +
  356 +// on the view
  357 +Text(controller.title.value), // .value olması gerekir
  358 +ListView.builder (
  359 + itemCount: controller.list.length // listelerin buna ihtiyacı yok
  360 +)
  361 +```
  362 +
  363 +Kendi sınıflarınızı observable hale getirirken, bunları güncellemenin farklı bir yolu vardır:
  364 +
  365 +``` dart
  366 +// model dosyasında
  367 +// her bir öznitelik yerine tüm sınıfı observable hale getireceğiz
  368 +class User() {
  369 + User({this.name = '', this.age = 0});
  370 + String name;
  371 + int age;
  372 +}
  373 +
  374 +// Controller dosyası
  375 +final user = User().obs;
  376 +// User değişkenini güncellemeniz gerektiğinde:
  377 +user.update( (user) { // bu parametre, güncellemek istediğiniz sınıfın kendisidir.
  378 +user.name = 'Jonny';
  379 +user.age = 18;
  380 +});
  381 +// user değişkenini güncellemenin alternatif bir yolu:
  382 +user(User(name: 'João', age: 35));
  383 +
  384 +// on view:
  385 +Obx(()=> Text("Name ${user.value.name}: Age: ${user.value.age}"))
  386 +// model değerlerine .value olmadan da erişebilirsiniz:
  387 +user().name;
  388 +```
  389 +
  390 +İstemiyorsanız setlerle çalışmak zorunda değilsiniz. "assign" ve "assignAll" api'sini kullanabilirsiniz.
  391 +"assign" api'si listenizi temizler ve oradan başlatmak istediğiniz tek bir nesneyi ekler.
  392 +"assignAll" api, mevcut listeyi temizleyecek ve ona enjekte ettiğiniz yinelenebilir nesneleri ekleyecektir.
  393 +
  394 +### Neden .value kullanmak zorundayım?
  395 +
  396 +Basit bir decoration ve code generator ile `String` ve `int` için 'value' kullanma zorunluluğunu kaldırabiliriz, ancak bu kütüphanenin amacı kesinlikle dış bağımlılıklardan kaçınmaktır. Temelleri (route, dependencies ve state management) içeren, harici bir pakete ihtiyaç duymadan basit, hafif ve performanslı bir şekilde programlamaya hazır bir ortam sunmak istiyoruz.
  397 +
  398 +Pubspec'inize (get) tam anlamıyla 3 harf ve iki nokta üst üste ekleyebilir ve programlamaya başlayabilirsiniz. Rota yönetiminden durum yönetimine kadar varsayılan olarak dahil edilen tüm çözümler kolaylık, üretkenlik ve performansı hedefler.
  399 +
  400 +Bu kitaplığın toplam ağırlığı, eksiksiz bir çözüm olmasına rağmen tek bir state manager'den daha azdır.
  401 +
  402 +
  403 +Eğer `.value` dan rahatsızsanız MobX harika bir alternatiftir ve Get ile birlikte kullanabilirsiniz.
  404 +
  405 +
  406 +MobX code generator ile bir sorununuz yoksa veya BLoC ilgili bir sorununuz yoksa Get ile route'u kullanabilirsiniz. Get SEM ve RSM ile doğdu, şirketimin 90'dan fazla controller'a sahip bir projesi var.Büyük bir projeniz varsa, oldukça iyi bir makinede bir Flutter Clean'den sonra görevlerini tamamlaması 30 dakikadan fazla sürdü. 5, 10, 15 controller, herhangi bir state manager size yardımcı olacaktır. Büyük bir projeniz varsa ve code generator sizin için bir sorunsa, bu çözüm size verildi.
  407 +
  408 +Açıkçası, birisi projeye katkıda bulunmak ve bir code generator veya benzeri bir şey oluşturmak istiyorsa, bunu readme'de alternatif olarak bağlantı ekleyeceğim, şimdilik diyorum ki, bunu zaten yapan iyi çözümler var, MobX gibi.
  409 +
  410 +### Obx()
  411 +
  412 +Bindings kullanarak Get yazmak gereksizdir. Yalnızca bir pencere öğesi oluşturan anonim işlevi alan GetX yerine Obx pencere aracını kullanabilirsiniz.
  413 +Açıkçası, bir tür kullanmıyorsanız, değişkenleri kullanmak için denetleyicinizin bir örneğine sahip olmanız veya değeri almak için `Get.find<Controller>()` .value veya Controller.to.value öğesini kullanmanız gerekir. .
  414 +
  415 +### Çalışanlar
  416 +
  417 +Bir olay meydana geldiğinde belirli geri aramaları tetikleyerek size yardımcı olacaktır.
  418 +
  419 +``` dart
  420 +/// 'Count1' her değiştiğinde çağrılır.
  421 +ever(count1, (_) => print("$_ has been changed"));
  422 +
  423 +/// $_ değişkeni yalnızca ilk kez değiştirildiğinde çağrılır.
  424 +once(count1, (_) => print("$_ was changed once"));
  425 +
  426 +/// Anti DDoS - Örneğin, kullanıcı 1 saniye boyunca yazmayı her durdurduğunda çağrılır.
  427 +debounce(count1, (_) => print("debouce$_"), time: Duration(seconds: 1));
  428 +
  429 +/// 1 saniye içinde tüm değişiklikleri yok sayın.
  430 +interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));
  431 +```
  432 +
  433 +Tüm çalışanlar (`debounce` dışında), "bool" veya "bool" döndüren bir callback olabilen bir "Koşul" adlı parametreye sahiptir.
  434 +Bu "koşul", "callback" işlevinin ne zaman yürütüleceğini tanımlar.
  435 +
  436 +Tüm çalışanlar, çalışanı iptal etmek için ( `dispose()` aracılığıyla) kullanabileceğiniz bir 'Worker' örneği döndürür.
  437 +
  438 +
  439 +* **`ever`**
  440 +
  441 +_Rx_ değişkeni her yeni bir değer yaydığında çağrılır.
  442 +
  443 +* **`everAll`**
  444 +
  445 +`ever` gibi, ancak değişkeni her değiştirildiğinde çağrılan _Rx_ değerlerinin bir `List`'ini alır. Bu kadar.
  446 +
  447 +* **`once`**
  448 +
  449 +'once', yalnızca değişken ilk değiştirildiğinde çağrılır.
  450 +
  451 +* **`debounce`**
  452 +
  453 +'debounce', yalnızca kullanıcı yazmayı bitirdiğinde API'nin çağrılmasını istediğiniz arama işlevlerinde çok kullanışlıdır. Kullanıcı "Jonny" yazarsa, apı'lerde J, o, n, n ve y harfleriyle 5 aramanız olur. Get ile bu olmaz, çünkü yalnızca yazmanın sonunda tetiklenecek bir "debounce" çalışanınız olur.
  454 +
  455 +* **`interval`**
  456 +
  457 +'interval' debouce'dan farklıdır. debouce kullanıcı 1 saniye içinde bir değişkene 1000 değişiklik yaparsa, öngörülen zamanlayıcıdan sonra yalnızca sonuncusunu gönderir (varsayılan değer 800 milisaniyedir). Interval bunun yerine, öngörülen süre boyunca tüm kullanıcı eylemlerini yoksayar. Olayları saniyede 1000 olmak üzere 1 dakika boyunca gönderirseniz, debounce yalnızca kullanıcı olayları engellemeyi bıraktığında size sonuncusunu gönderir. aralık, her saniye olayları teslim eder ve 3 saniyeye ayarlanırsa, o dakika 20 olay teslim eder. Bu, kullanıcının bir şeye hızlı bir şekilde tıklayabileceği ve bir avantaj elde edebileceği işlevlerde kötüye kullanımı önlemek için önerilir (kullanıcının bir şeye tıklayarak para kazanabileceğini düşünün, aynı dakikada 300 kez tıklarsa, 300 jetona sahip olur, aralığı kullanarak, bir zaman dilimi ayarlayabilirsiniz 3 saniye boyunca ve hatta 300 veya bin kez tıklandığında, 1 dakika içinde alacağı maksimum 20 jeton, 300 veya 1 milyon kez tıklanır). Debounce, anti-DDoS için, Onchange'deki her değişikliğin apı'nizde bir sorguya neden olacağı arama gibi işlevler için uygundur. Debounce, kullanıcının isteği yapmak için adı yazmayı bırakmasını bekleyecektir. Yukarıda belirtilen jeton senaryosunda kullanılmış olsaydı, kullanıcı yalnızca belirlenen süre boyunca "durakladığında" çalıştırıldığı için kullanıcı yalnızca 1 jeton kazanırdı.
  458 +
  459 +* NOT: Çalışanlar her zaman bir Controller veya Class başlatırken kullanılmalıdır, bu nedenle her zaman onInit (önerilen), Class oluşturucu veya statefulwidget'in initState üzerinde olmalıdır (bu uygulama çoğu durumda önerilmez, ancak herhangi bir yan etkisi olmamalıdır).
  460 +
  461 +## Simple State Manager(Basit Durum Yöneticisi)
  462 +
  463 +Get'in son derece hafif ve kolay, ChangeNotifier kullanmayan, özellikle Flutter'a yeni başlayanların ihtiyacını karşılayacak ve büyük uygulamalar için sorun yaratmayacak bir state manager'i var.
  464 +
  465 +GetBuilder tam olarak çoklu state controller'a yöneliktir. Bir sepete 30 ürün eklediğinizi, birini sil'i tıklattığınızı, aynı zamanda listenin güncellendiğini, fiyatın güncellendiğini ve alışveriş sepetindeki rozetin daha küçük bir sayıya güncellendiğini düşünün. Bunu GetBuilder yapar, çünkü durumları gruplandırır ve bunun için herhangi bir "hesaplama mantığı" olmadan hepsini bir kerede değiştirir. GetBuilder, bu tür bir durum göz önünde bulundurularak oluşturuldu, çünkü geçici durum değişikliği için Setstate'i kullanabilirsiniz ve bunun için bir state manager'e ihtiyacınız olmaz.
  466 +
  467 +Bu şekilde, tek bir controller'a ihtiyacınız varsa, bunun için ID'ler atayabilir veya getx'i kullanabilirsiniz. Bu size kalmış, sahip olduğunuz daha fazla "individual" widget'ın, getx'in performansının o kadar fazla öne çıkacağını, Getbuilder'ın performansının ise birden fazla durum değişikliği olduğunda üstün olması gerektiğini unutmayın.
  468 +
  469 +### Avantajlar
  470 +
  471 +1. Yalnızca gerekli widget'ları günceller.
  472 +
  473 +2. ChangeNotifier kullanmaz, daha az bellek kullanan (0mb'ye yakın) durum yöneticisidir.
  474 +
  475 +3. StatefulWidget'ı unutun! Get ile buna asla ihtiyacınız olmayacak. Diğer state manager'lar ile (BLoC, MobX Controller vb.) muhtemelen bir StatefulWidget kullanmanız gerekecek. Stateless Widget mı? Öyleyse, yalnızca state bilgisi olan Widget'ın durumunu kaydedebiliyorsanız, neden tüm sınıfın durumunu kurtarın? Get bunu da çözer. Stateless bir sınıf oluşturun, her şeyi Stateless yapın. Tek bir bileşeni güncellemeniz gerekiyorsa, onu GetBuilder ile sarın.
  476 +
  477 +4. Projenizi gerçek anlamda düzenleyin! Denetleyiciler UI'nizde bulunmamalı, TextEditController'ınızı veya kullandığınız herhangi bir denetleyiciyi Controller sınıfınıza yerleştirmemelidir.
  478 +
  479 +5.Bir widget'ı oluşturulduğu anda güncellemek için bir olayı tetiklemeniz mi gerekiyor? GetBuilder, StatefulWidget gibi "initState" özelliğine sahiptir ve initState'inize daha fazla event yerleştirilmeden, doğrudan denetleyicinizden event'leri çağırabilirsiniz.
  480 +
  481 +6. Stream, timer vb. kapatmak gibi bir eylemi tetiklemeniz gerekiyor mu? Get Builder ayrıca, widget yok edilir edilmez olayları çağırabileceğiniz dispose özelliğine de sahiptir.
  482 +
  483 +7. Stream'leri yalnızca gerektiğinde kullanın. Stream Controller controller içinde normal olarak kullanabilir ve Streambuilder'ı da normal olarak kullanabilirsiniz, ancak unutmayın, bir stream makul bir şekilde bellek tüketir, reaktif programlama güzeldir, ancak kötüye kullanmamalısınız. aynı anda açılan 30 stream, Changenotifier'den daha kötü olabilir (ve changeNotifier çok kötüdür).
  484 +
  485 +8. Ram harcamadan widget'ları güncelleyin. Get yalnızca Get Builderlder içerik oluşturucu kimliğini ve gerektiğinde GetBuilder güncelleştirmelerini depolar. Bellekte get ID depolama bellek tüketimi bile GetBuilders binlerce çok düşüktür. Yeni bir GetBuilder oluşturduğunuzda, aslında bir içerik oluşturucu kimliği olan GetBuilder durumunu paylaşıyorsunuz demektir. Her GetBuilder için büyük uygulamalar için çok fazla ram tasarrufu sağlayan yeni bir durum oluşturulmaz. Temel olarak uygulamanız tamamen Stateless olacak ve State Bilgisi olan birkaç Widget (GetBuilder içinde) tek bir duruma sahip olacak ve bu nedenle birini güncellemek hepsini güncelleyecektir. State sadece bir tanesidir.
  486 +
  487 +9. Get her şeyi bilir ve çoğu durumda bir denetleyiciyi bellekten çıkarma zamanını tam olarak bilir. Bir denetleyiciyi ne zaman elden çıkaracağınız konusunda endişelenmemelisiniz, Bunu yapmak için en iyi zamanı öğrenin.
  488 +
  489 +### Kullanımı
  490 +
  491 +``` dart
  492 +// Controller sınıfı oluşturun ve GetxController'ı extends edin
  493 +class Controller extends GetxController {
  494 + int counter = 0;
  495 + void increment() {
  496 + counter++;
  497 + update(); // artış çağrıldığında kullanıcı arayüzünde sayaç değişkenini güncellemek için update() işlevini kullanın
  498 + }
  499 +}
  500 +// Stateless/Stateful sınıfınızda, artış çağrıldığında Metni güncellemek için Get Builder'ı kullanın
  501 +GetBuilder<Controller>(
  502 + init: Controller(), // INIT IT ONLY THE FIRST TIME
  503 + builder: (_) => Text(
  504 + '${_.counter}',
  505 + ),
  506 +)
  507 +
  508 +//Initialize yalnızca ilk kez başlatın. Aynı controller için ReBuilder'ı ikinci kez kullanıyorsanız, tekrar kullanmayın. Controller'ınız, onu 'init' olarak işaretleyen pencere öğesi yerleştirildiği anda bellekten otomatik olarak kaldırılacaktır. Bunun için endişelenmenize gerek yok, Get bunu otomatik olarak yapacak, sadece aynı contrroller'ın iki kez başlatmadığınızdan emin olun.
  509 +```
  510 +
  511 +**Tamamlandı!**
  512 +
  513 +* Get ile durumları nasıl yöneteceğinizi öğrendiniz.
  514 +
  515 +* Not: Daha büyük bir organizasyon isteyebilirsiniz ve init özelliğini kullanmayabilirsiniz. Bunun için bir sınıf oluşturup Bindings sınıfını extends edebilir ve bunun içinde o rotada oluşturulacak controller'dan bahsedebilirsiniz. Controller'lar o anda oluşturulmaz, tam tersine, bu sadece bir ifadedir, böylece bir Controller'ı ilk kullandığınızda, nereye bakacağınızı bilecek. Get lazyLoad olarak kalacak ve artık ihtiyaç duyulmadığında Controller'ları elden çıkarmaya devam edecek. Nasıl çalıştığını görmek için pub.dev örneğine bakın.
  516 +
  517 +Birçok rotada gezinirseniz ve daha önce kullandığınız controller'ınızda bulunan verilere ihtiyacınız varsa, GetBuilder tekrar (init olmadan) kullanmanız yeterlidir:
  518 +
  519 +``` dart
  520 +class OtherClass extends StatelessWidget {
  521 + @override
  522 + Widget build(BuildContext context) {
  523 + return Scaffold(
  524 + body: Center(
  525 + child: GetBuilder<Controller>(
  526 + builder: (s) => Text('${s.counter}'),
  527 + ),
  528 + ),
  529 + );
  530 + }
  531 +
  532 +```
  533 +
  534 +Controller'ınızı GetBuilder dışında birçok başka yerde kullanmanız gerekiyorsa, controller'ınıza bir get oluşturun ve kolayca elde edin. (veya `Get.find<Controller>()` kullanın)
  535 +
  536 +``` dart
  537 +class Controller extends GetxController {
  538 +
  539 + /// Buna ihtiyacın yok. Sadece syntax kolaylığı için kullanmanızı öneririm.
  540 + /// statik yöntemle: Controller.to.increment();
  541 + /// statik yöntem olmadan: Get.find<Controller>().increment();
  542 + /// Her iki syntax kullanmanın herhangi bir yan etkisi veya performans farkı yoktur. Yalnızca birinin türe ihtiyacı yoktur ve diğeri IDE tarafından otomatik olarak tamamlanır.
  543 + static Controller get to => Get.find(); // bu satırı ekleyin
  544 +
  545 + int counter = 0;
  546 + void increment() {
  547 + counter++;
  548 + update();
  549 + }
  550 +}
  551 +```
  552 +
  553 +Ve sonra controller'a doğrudan bu şekilde erişebilirsiniz:
  554 +
  555 +``` dart
  556 +FloatingActionButton(
  557 + onPressed: () {
  558 + Controller.to.increment(),
  559 + } // Bu inanılmaz derecede basit!
  560 + child: Text("${Controller.to.counter}"),
  561 +),
  562 +```
  563 +
  564 +FloatingActionButton tuşuna bastığınızda, 'counter' değişkenini dinleyen tüm widget'lar otomatik olarak güncellenir.
  565 +
  566 +### Controller'lar nasıl çalışır
  567 +
  568 +Diyelim ki elimizde bu var:
  569 +
  570 + `Class a => Class B (has controller X) => Class C (has controller X)`
  571 +
  572 +A sınıfında controller henüz bellekte değil çünkü henüz kullanmadınız (Get is lazyLoad). B sınıfında controller kullandınız ve belleğe girdi. C sınıfında, B sınıfındakiyle aynı controller'ı kullandınız, Get, controller B'nin durumunu C controller'ı ile paylaşacak ve aynı controller hala bellekte kalacaktır. C ekranını ve B ekranını kapatırsanız, Get, A Sınıfı controller'ı kullanmadığından otomatik olarak X controller'ını bellekten alır ve kaynakları boşaltır. Tekrar B'ye giderseniz, X controller'ı tekrar belleğe girer, C sınıfına gitmek yerine tekrar A sınıfına dönerseniz Get, controller aynı şekilde bellekten çıkarır. C sınıfı controller'ı kullanmadıysa ve B sınıfını bellekten çıkardıysanız, hiçbir sınıf controller'ı X kullanmayacak ve aynı şekilde imha edilecektir. Get ile bulaşabilecek tek istisna, B'yi rotadan beklenmedik bir şekilde kaldırırsanız ve controller'ı C'de kullanmaya çalışırsanız. Bu durumda, controller'ın B'deki ID silindi ve Get şu şekilde programlandı: ID olmayan her controller'ı bellekten kaldırın. Bunu yapmayı düşünüyorsanız, "autoRemove: false" işaretini B sınıfının GetBuilder'ına ekleyin ve adoptID = true; yapın C sınıfında GetBuilder kullanın.
  573 +
  574 +### Artık StatefulWidget'lara ihtiyacınız olmayacak
  575 +
  576 +Stateful Widget kullanmak, tüm ekranların durumunu gereksiz yere depolamak anlamına gelir, çünkü bir widget'ı minimum düzeyde yeniden oluşturmanız gerekse bile, onu başka bir Stateful Widget olacak olan bir Consumer/Observer/BlocProvider/GetBuilder/GetX/Obx içine gömeceksiniz. StatefulWidget sınıfı, daha fazla RAM tahsis edecek olan StatelessWidget'ten daha büyük bir sınıftır ve bu, bir veya iki sınıf arasında önemli bir fark yaratmayabilir, ancak 100 tanesine sahip olduğunuzda kesinlikle yapacaktır! TickerProviderStateMixin gibi bir mixin kullanmanız gerekmiyorsa, Get ile bir StatefulWidget kullanmak tamamen gereksiz olacaktır.
  577 +
  578 +StatefulWidget'ın tüm yöntemlerini doğrudan bir GetBuilder'dan çağırabilirsiniz.
  579 +Örneğin, initState() veya Dispose() yöntemini çağırmanız gerekiyorsa, bunları doğrudan çağırabilirsiniz;
  580 +
  581 +``` dart
  582 +GetBuilder<Controller>(
  583 + initState: (_) => Controller.to.fetchApi(),
  584 + dispose: (_) => Controller.to.closeStreams(),
  585 + builder: (s) => Text('${s.username}'),
  586 +),
  587 +```
  588 +
  589 +Bundan çok daha iyi bir yaklaşım, doğrudan controller'dan onInit() ve onClose() yöntemini kullanmaktır.
  590 +
  591 +``` dart
  592 +@override
  593 +void onInit() {
  594 + fetchApi();
  595 + super.onInit();
  596 +}
  597 +```
  598 +
  599 +* NOT: Controller ilk kez çağrıldığı anda bir metot başlatmak istiyorsanız, bunun için constructors kullanmanıza GEREK YOKTUR, aslında Get gibi performans odaklı bir paket kullanarak bu sorunu çözebilirsiniz. Controller'ların oluşturulduğu veya tahsis edildiği mantıktan saptığı için (bu controller'ın bir örneğini oluşturursanız, constructor hemen çağrılır, bir controller kullanılmadan önce bellek ayırırsınız ve belleği doldurursunuz. Bu kesinlikle bu kütüphanenin ilkelerine zarar verir. onInit() yöntemleri; ve onClose(); için oluşturulduysa, Get.lazyPut kullanıp kullanmadığınıza bağlı olarak Controller oluşturulduğunda veya ilk kez kullanıldığında çağrılırlar. Örneğin, verileri doldurmak için API'nize bir çağrı yapmak istiyorsanız, eski moda initState/dispose yöntemini unutabilirsiniz, sadece onInit'te api'ye çağrınızı başlatın ve herhangi bir komutu çalıştırmanız gerekirse akışları kapatmak gibi, bunun için onClose()'u kullanın.
  600 +
  601 +### Neden var
  602 +
  603 +Bu paketin amacı, mümkün olan en az bağımlılıkları kullanarak, yüksek derecede ayrıştırma ile rotaların gezinmesi, bağımlılıkların ve durumların yönetimi için eksiksiz bir çözüm sunmaktır. Get, mümkün olan en az bağlantıyla çalıştığınızdan emin olmak için tüm yüksek ve düşük seviyeli Flutter API'lerini kendi içinde çalıştırır. Projenizde herhangi bir bağlantı olmadığından emin olmak için her şeyi tek bir pakette merkezileştiriyoruz. Bu şekilde, görünümünüze yalnızca widget'lar koyabilir ve ekibinizin iş mantığıyla çalışan bölümünü, Görünümün herhangi bir öğesine bağlı kalmadan iş mantığıyla çalışmak üzere serbest bırakabilirsiniz. Bu, çok daha temiz bir çalışma ortamı sağlar, böylece ekibinizin bir kısmı controller'a veri göndermekten endişe etmeden yalnızca widget'larla çalışır ve ekibinizin bir kısmı, görünümün hiçbir öğesine bağlı kalmadan yalnızca genişliğindeki iş mantığıyla çalışır.
  604 +
  605 +Yani bunu basitleştirirsek:
  606 +Initstate'deki yöntemleri çağırmanız ve bunları controller'ınıza parametre ile göndermeniz veya bunun için controller içerisinde constructor kullanmanız gerekmez, doğru zamanda çağrılan onInit () yöntemine sahip olursunuz.
  607 +Cihaz aramak zorunda değilsiniz, gerektiğinde tam zamanında close() yöntemi ile hafızasından silinecektir. Bu şekilde, yalnızca widget'lar için görünümler bırakın, her türlü iş mantığından kaçının.
  608 +
  609 +GetxController içinde bir dispose yöntemi çağırmayın, hiçbir şey yapmaz, controller'ın bir Widget olmadığını, "dispose" gerektiğini ve Get tarafından bellekten otomatik ve akıllıca kaldırılacağını unutmayın. Üzerinde herhangi bir akış kullandıysanız ve kapatmak istiyorsanız, onu close yöntemine eklemeniz yeterlidir. Örnek:
  610 +
  611 +
  612 +``` dart
  613 +class Controller extends GetxController {
  614 + StreamController<User> user = StreamController<User>();
  615 + StreamController<String> name = StreamController<String>();
  616 +
  617 + /// close stream = onClose yöntemi, dispose değil.
  618 + @override
  619 + void onClose() {
  620 + user.close();
  621 + name.close();
  622 + super.onClose();
  623 + }
  624 +}
  625 +```
  626 +
  627 +Controller life cycle(yaşam döngüsü):
  628 +
  629 +* onInit() oluşturulduğu yer.
  630 +* onClose() close yöntemine hazırlanırken herhangi bir değişiklik yapmak için kapatıldığı yer.
  631 +* deleted: Controller bellekten tam anlamıyla kaldırdığı için bu API'ye erişiminiz olmaz. Herhangi bir iz bırakmadan kelimenin tam anlamıyla silinir.
  632 +
  633 +### Kullanmanın diğer yolları
  634 +
  635 +
  636 +Controller'ı doğrudan GetBuilder ile kullanabilirsiniz:
  637 +
  638 +``` dart
  639 +GetBuilder<Controller>(
  640 + init: Controller(),
  641 + builder: (value) => Text(
  642 + '${value.counter}', //here
  643 + ),
  644 +),
  645 +```
  646 +
  647 +Controller'ınızı GetBuilder dışında bir örneğine de ihtiyacınız olabilir ve bunu başarmak için bu yaklaşımları kullanabilirsiniz:
  648 +
  649 +``` dart
  650 +class Controller extends GetxController {
  651 + static Controller get to => Get.find();
  652 +[...]
  653 +}
  654 +// görünümde:
  655 +GetBuilder<Controller>(
  656 + init: Controller(), // Her controller'ı bir kez kullanın
  657 + builder: (_) => Text(
  658 + '${Controller.to.counter}', //burada
  659 + )
  660 +),
  661 +```
  662 +
  663 +or
  664 +
  665 +``` dart
  666 +class Controller extends GetxController {
  667 + // static Controller get to => Get.find(); // static olmadan
  668 +[...]
  669 +}
  670 +// on stateful/stateless class
  671 +GetBuilder<Controller>(
  672 + init: Controller(), // Her controller'ı bir kez kullanın
  673 + builder: (_) => Text(
  674 + '${Get.find<Controller>().counter}', //burada
  675 + ),
  676 +),
  677 +```
  678 +
  679 +* Bunu yapmak için "non-canonical" yaklaşımları kullanabilirsiniz. Get_it, modular vb. Gibi başka bir dependency manager kullanıyorsanız ve sadece controller instance etmek istiyorsanız, bunu yapabilirsiniz:
  680 +
  681 +``` dart
  682 +Controller controller = Controller();
  683 +[...]
  684 +GetBuilder<Controller>(
  685 + init: controller, //burada
  686 + builder: (_) => Text(
  687 + '${controller.counter}', // burada
  688 + ),
  689 +),
  690 +
  691 +```
  692 +
  693 +### Unique IDs-Benzersiz Kimlikler
  694 +
  695 +Bir widget'ın controller'ını güncellemek istiyorsanız GetBuilder onlara benzersiz kimlikler atayabilirsiniz:
  696 +
  697 +``` dart
  698 +GetBuilder<Controller>(
  699 + id: 'text'
  700 + init: Controller(), // Her controller'ı bir kez kullanın
  701 + builder: (_) => Text(
  702 + '${Get.find<Controller>().counter}', //burada
  703 + ),
  704 +),
  705 +```
  706 +
  707 +Ve bu formu güncelleyin:
  708 +
  709 +``` dart
  710 +update(['text']);
  711 +```
  712 +
  713 +Güncelleme için koşullar da uygulayabilirsiniz:
  714 +
  715 +``` dart
  716 +update(['text'], counter < 10);
  717 +```
  718 +
  719 +GetX bunu otomatik olarak yapar ve yalnızca değiştirilen değişkeni tam olarak kullanan widget'ı yeniden yapılandırır, bir değişkeni öncekiyle aynı olacak şekilde değiştirirseniz ve bu state değişikliği anlamına gelmezse GetX widget'ı bellek ve CPU döngülerinden tasarruf etmek için yeniden oluşturmaz (ekranda 3 görüntüleniyor ve değişkeni tekrar 3 olarak değiştirirsiniz. Çoğu state manager, bu yeni bir yeniden yapılanmaya neden olur, ancak Get ile widget yalnızca state değiştiyse yeniden oluşturulur).
  720 +
  721 +## İki state managers ile Mixing
  722 +
  723 +Bazı insanlar, yalnızca bir tür reaktif değişken ve diğer mekanikleri kullanmak istediklerinden ve bunun için bir GetBuilder'a bir Obx eklemeleri gerektiğinden bir özellik request'i açtı. Bunu düşünerek MixinBuilder oluşturuldu. Hem ".obs" değişkenlerini değiştirerek reaktif değişikliklere hem de update() aracılığıyla mekanik güncellemelere izin verildi. Bununla birlikte, 4 widget'tan en çok kaynak tüketendir, çünkü children'larda değişiklik olaylarını anlaması için sahip olmasının yanı sıra, controller'ın güncelleme yöntemine sahip olur.
  724 +
  725 +GetxController'ı extends etmek önemlidir, çünkü yaşam döngüleri vardır ve olayları onInit() ve onClose() yöntemlerinde "başlatabilir" ve "bitebilir". Bunun için herhangi bir sınıfı kullanabilirsiniz, ancak değişkenlerinizi observable olsun ya da olmasın yerleştirmek için GetxController sınıfını kullanmanızı şiddetle tavsiye ederim.
  726 +
  727 +## StateMixin
  728 +
  729 +`UI` state'ini ele almanın başka bir yolu da `StateMixin<T>` kullanmaktır.
  730 +Bunu uygulamak için, `StateMixin<T>` ile `with`i kullanın.
  731 +bir controller'a T modelinizi ekleyin.
  732 +
  733 +``` dart
  734 +class Controller extends GetController with StateMixin<User>{}
  735 +```
  736 +
  737 +
  738 +`change()` yöntemi istediğimiz zaman State'i değiştirir.
  739 +Sadece verileri ve state'i bu şekilde iletin:
  740 +
  741 +```dart
  742 +change(data, status: RxStatus.success());
  743 +```
  744 +
  745 +RxStatus şu duruma izin verir:
  746 +
  747 +``` dart
  748 +RxStatus.loading();
  749 +RxStatus.success();
  750 +RxStatus.empty();
  751 +RxStatus.error('message');
  752 +```
  753 +
  754 +UI'da bu şekilde kullanın:
  755 +
  756 +```dart
  757 +class OtherClass extends GetView<Controller> {
  758 + @override
  759 + Widget build(BuildContext context) {
  760 + return Scaffold(
  761 +
  762 + body: controller.obx(
  763 + (state)=>Text(state.name),
  764 +
  765 + // burada özel yükleme göstergenizi koyabilirsiniz, ancak
  766 + // varsayılan olarak Center(child:CircularProgressIndicator()) olacaktır.
  767 + onLoading: CustomLoadingIndicator(),
  768 + onEmpty: Text('No data found'),
  769 +
  770 + // burada ayrıca kendi hata widget'ınızı ayarlayabilirsiniz, ancak
  771 + // default birCenter(child:Text(error)) olacaktır.
  772 + onError: (error)=>Text(error),
  773 + ),
  774 + );
  775 +}
  776 +```
  777 +
  778 +## GetBuilder vs GetX vs Obx vs MixinBuilder
  779 +
  780 +Programlamayla geçen on yılda bazı değerli dersler öğrenebildim.
  781 +
  782 +Reaktif programlama ile ilk temasım çok "vay be, bu inanılmaz" oldu ve aslında reaktif programlama inanılmaz.
  783 +Ancak, tüm durumlar için uygun değildir. Çoğu zaman tek ihtiyacınız olan, aynı anda 2 veya 3 parçacığın durumunu değiştirmek veya geçici bir durum değişikliğidir, bu durumda reaktif programlama kötü değildir, ancak uygun değildir.
  784 +
  785 +Reaktif programlama, bireysel iş akışıyla telafi edilebilecek daha yüksek bir RAM tüketimine sahiptir; bu, yalnızca bir widget'ın yeniden oluşturulmasını ve gerektiğinde yapılmasını sağlar, ancak her biri birkaç akışa sahip 80 nesneden oluşan bir liste oluşturmak iyi bir fikir değildir. Dartı açın ve bir StreamBuilder'ın ne kadar tükettiğini kontrol edin ve size ne söylemeye çalıştığımı anlayacaksınız.
  786 +
  787 +Bunu akılda tutarak, basit bir state manager yarattım. Bu basittir ve ondan tam olarak talep etmeniz gereken şey budur: State'i bloklar halinde basit bir şekilde ve en ekonomik şekilde güncellemek.
  788 +
  789 +GetBuilder RAM'de çok ekonomiktir ve ondan daha ekonomik bir yaklaşım yoktur (en azından ben bir tane hayal edemiyorum, varsa lütfen bize bildirin).
  790 +
  791 +Ancak GetBuilder hala mekanik bir state manager'dir, tıpkı Provider'ın notifyListeners() işlevini çağırmanız gerektiği gibi update() öğesini çağırmanız gerekir.
  792 +
  793 +Reaktif programlamanın gerçekten ilginç olduğu başka durumlar da vardır ve onunla çalışmamak, tekerleği yeniden icat etmekle aynı şeydir. Bunu akılda tutarak GetX, bir State Manager'de en modern ve gelişmiş olan her şeyi sağlamak için oluşturuldu. Sadece gerekli olanı günceller ve gerektiğinde, bir hatanız varsa ve aynı anda 300 durum değişikliği gönderirseniz GetX, yalnızca durum gerçekten değiştiğinde ekranı filtreler ve günceller.
  794 +
  795 +GetX, diğer herhangi bir reaktif durum yöneticisinden hala daha ekonomiktir, ancak GetBuilder'dan biraz daha fazla RAM tüketir. Bunu düşünerek ve Obx'in yarattığı kaynakların tüketimini en üst düzeye çıkarmayı hedefleyerek. GetX ve GetBuilder'dan farklı olarak, bir Obx içinde bir controller başlatamayacaksınız, bu sadece children'larda değişiklik olaylarını alan bir StreamSubscription'a sahip bir Widget'tır, hepsi bu. GetX'ten daha ekonomiktir, ancak reaktif olduğu için beklendiği gibi GetBuilder'a kaydeder ve GetBuilder, bir parçacığın hashcode'unu ve StateSetter'ını depolamak için var olan en basit yaklaşıma sahiptir. Obx ile controller türünüzü yazmanız gerekmez ve değişikliği birden çok farklı controller'dan ulaşabilir ve dinleyebilirsiniz, ancak bu readme dosyasının başındaki örnek yaklaşım kullanılarak veya Bindings classı kullanılarak daha önce başlatılması gerekir.
@@ -3,14 +3,18 @@ import 'dart:io'; @@ -3,14 +3,18 @@ import 'dart:io';
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:flutter_test/flutter_test.dart'; 4 import 'package:flutter_test/flutter_test.dart';
5 import 'package:get/get.dart'; 5 import 'package:get/get.dart';
6 -import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';  
7 -import 'package:get_demo/pages/home/domain/entity/cases_model.dart';  
8 -import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart';  
9 // import 'package:get_demo/routes/app_pages.dart'; 6 // import 'package:get_demo/routes/app_pages.dart';
10 // import 'package:get_test/get_test.dart'; 7 // import 'package:get_test/get_test.dart';
11 import 'package:matcher/matcher.dart' as m; 8 import 'package:matcher/matcher.dart' as m;
12 9
  10 +
  11 +import '../lib/pages/home/domain/adapters/repository_adapter.dart';
  12 +import '../lib/pages/home/domain/entity/cases_model.dart';
  13 +import '../lib/pages/home/presentation/controllers/home_controller.dart';
  14 +
  15 +
13 class MockRepositorySuccess implements IHomeRepository { 16 class MockRepositorySuccess implements IHomeRepository {
  17 +
14 @override 18 @override
15 Future<CasesModel> getCases() async { 19 Future<CasesModel> getCases() async {
16 return CasesModel( 20 return CasesModel(