- [Управление маршрутами](#управление-маршрутами) - [Как использовать](#как-использовать) - [Навигация без именованных маршрутов](#навигация-без-именованных-маршрутов) - [Навигация по именованным маршрутам](#навигация-по-именованным-маршрутам) - [Отправить данные по именованному маршруту](#отправить-данные-по-именованному-маршруту) - [Динамические url-ссылки](#динамические-url-ссылки) - [Middleware](#middleware) - [Навигация без контекста](#навигация-без-контекста) - [SnackBars](#snackbars) - [Dialogs](#dialogs) - [BottomSheets](#bottomsheets) - [Вложенная навигация](#вложенная-навигация) # Управление маршрутами Это полное объяснение всего, что нужно Getx, когда речь идет об управлении маршрутами. ## Как использовать Добавьте к вашему pubspec.yaml следующее: ```yaml dependencies: get: ``` Если вы собираетесь использовать маршруты/snackbars/dialogs/bottomSheets без контекста или использовать высокоуровневые API Get, вам нужно просто добавить «Get» перед вашим MaterialApp, превратив его в GetMaterialApp! ```dart GetMaterialApp( // Before: MaterialApp( home: MyHome(), ) ``` ## Навигация без именованных маршрутов Для навигации на новый экран: ```dart Get.to(NextScreen()); ``` Чтобы закрыть snackbars, диалог, bottomsheets, или все, что вы обычно закрывали с помощью Navigator.pop(context); ```dart Get.back(); ``` Для перехода к следующему экрану и отсутствия возможности вернуться к предыдущему экрану (для использования в SplashScreens, экранах входа и т.д.) ```dart Get.off(NextScreen()); ``` Для перехода к следующему экрану и отмены всех предыдущих маршрутов (полезно в корзинах для покупок, опросах и тестах) ```dart Get.offAll(NextScreen()); ``` Чтобы перейти к следующему маршруту и ​​получить или обновить данные, как только вы вернетесь с него: ```dart var data = await Get.to(Payment()); ``` отправить данные на предыдущий экран: ```dart Get.back(result: 'success'); ``` И использовать их: пример: ```dart if(data == 'success') madeAnything(); ``` Нет желания учить наш синтаксис? Просто измените Navigator(верхний регистр) на navigator (нижний регистр), и вы получите все функции стандартной навигации без использования контекста. Пример: ```dart // Default Flutter navigator Navigator.of(context).push( context, MaterialPageRoute( builder: (BuildContext context) { return HomePage(); }, ), ); // Get using Flutter syntax without needing context navigator.push( MaterialPageRoute( builder: (_) { return HomePage(); }, ), ); // Get syntax (It is much better, but you have the right to disagree) Get.to(HomePage()); ``` ## Навигация по именованным маршрутам - Если вы предпочитаете перемещаться по именованным маршрутам, Get также поддерживает это. Для навигации на следующий экран ```dart Get.toNamed("/NextScreen"); ``` Для навигации и удаления предыдущего экрана из дерева. ```dart Get.offNamed("/NextScreen"); ``` Для навигации и удаления всех предыдущих экранов из дерева. ```dart Get.offAllNamed("/NextScreen"); ``` Для определения маршрутов используйте GetMaterialApp: ```dart void main() { runApp( GetMaterialApp( initialRoute: '/', getPages: [ GetPage(name: '/', page: () => MyHomePage()), GetPage(name: '/second', page: () => Second()), GetPage( name: '/third', page: () => Third(), transition: Transition.zoom ), ], ) ); } ``` Для обработки навигации по неопределенным маршрутам (ошибка 404) вы можете определить страницу unknownRoute в GetMaterialApp. ```dart void main() { runApp( GetMaterialApp( unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()), initialRoute: '/', getPages: [ GetPage(name: '/', page: () => MyHomePage()), GetPage(name: '/second', page: () => Second()), ], ) ); } ``` ### Отправить данные по именованному маршруту Просто отправьте то, что хотите в качестве аргументов. Get принимает здесь всё, что угодно, будь то String, Map, List или даже экземпляр класса. ```dart Get.toNamed("/NextScreen", arguments: 'Get is the best'); ``` в вашем классе или контроллере: ```dart print(Get.arguments); //print out: Get is the best ``` ### Динамические url-ссылки Получите расширенные динамические url-адреса, как в Интернете. Веб-разработчики, вероятно, уже хотели эту функцию на Flutter, и, скорее всего, видели, что пакет обещает эту функцию и предоставляет совершенно другой синтаксис, чем url-адрес в Интернете, но Get также решает эту проблему. ```dart Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo"); ``` в вашем controller/bloc/stateful/stateless классе: ```dart print(Get.parameters['id']); // out: 354 print(Get.parameters['name']); // out: Enzo ``` Вы также можете легко получить именованные параметры с помощью Get: ```dart void main() { runApp( GetMaterialApp( initialRoute: '/', getPages: [ GetPage( name: '/', page: () => MyHomePage(), ), GetPage( name: '/profile/', page: () => MyProfile(), ), //You can define a different page for routes with arguments, and another without arguments, but for that you must use the slash '/' on the route that will not receive arguments as above. GetPage( name: '/profile/:user', page: () => UserProfile(), ), GetPage( name: '/third', page: () => Third(), transition: Transition.cupertino ), ], ) ); } ``` Отправьте данные по именованному маршруту ```dart Get.toNamed("/profile/34954"); ``` На втором экране возьмите данные по параметрам ```dart print(Get.parameters['user']); // out: 34954 ``` или отправьте несколько таких параметров ```dart Get.toNamed("/profile/34954?flag=true"); ``` На втором экране взять данные по параметрам как обычно. ```dart print(Get.parameters['user']); print(Get.parameters['flag']); // out: 34954 true ``` И теперь все, что вам нужно сделать, это использовать Get.toNamed() для навигации по именованным маршрутам без какого-либо контекста (вы можете вызывать свои маршруты непосредственно из класса BLoC или контроллера), а когда ваше приложение будет скомпилировано в Интернете, ваше маршруты появятся в url <3 ### Middleware Если вы хотите прослушивать события Get для запуска действий, вы можете использовать для этого routingCallback ```dart GetMaterialApp( routingCallback: (routing) { if(routing.current == '/second'){ openAds(); } } ) ``` Если вы не используете GetMaterialApp, вы можете использовать ручной API для подключения наблюдателя. ```dart void main() { runApp( MaterialApp( onGenerateRoute: Router.generateRoute, initialRoute: "/", navigatorKey: Get.key, navigatorObservers: [ GetObserver(MiddleWare.observer), // HERE !!! ], ), ); } ``` Создайте класс MiddleWare ```dart class MiddleWare { static observer(Routing routing) { /// You can listen in addition to the routes, the snackbars, dialogs and bottomsheets on each screen. ///If you need to enter any of these 3 events directly here, ///you must specify that the event is != Than you are trying to do. if (routing.current == '/second' && !routing.isSnackbar) { Get.snackbar("Hi", "You are on second route"); } else if (routing.current =='/third'){ print('last route called'); } } } ``` Теперь используйте Get в своем коде: ```dart class First extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.add), onPressed: () { Get.snackbar("hi", "i am a modern snackbar"); }, ), title: Text('First Route'), ), body: Center( child: ElevatedButton( child: Text('Open route'), onPressed: () { Get.toNamed("/second"); }, ), ), ); } } class Second extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.add), onPressed: () { Get.snackbar("hi", "i am a modern snackbar"); }, ), title: Text('second Route'), ), body: Center( child: ElevatedButton( child: Text('Open route'), onPressed: () { Get.toNamed("/third"); }, ), ), ); } } class Third extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Third Route"), ), body: Center( child: ElevatedButton( onPressed: () { Get.back(); }, child: Text('Go back!'), ), ), ); } } ``` ## Навигация без контекста ### SnackBars Чтобы получить простой SnackBar с Flutter, вы должны получить контекст Scaffold, или вы должны использовать GlobalKey, прикрепленный к вашему Scaffold ```dart final snackBar = SnackBar( content: Text('Hi!'), action: SnackBarAction( label: 'I am a old and ugly snackbar :(', onPressed: (){} ), ); // Find the Scaffold in the widget tree and use // it to show a SnackBar. Scaffold.of(context).showSnackBar(snackBar); ``` Реализация в Get: ```dart Get.snackbar('Hi', 'i am a modern snackbar'); ``` С Get всё, что вам нужно сделать, это вызвать Get.snackbar из любого места кода или настроить его так, как вы хотите! ```dart Get.snackbar( "Hey i'm a Get SnackBar!", // title "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message icon: Icon(Icons.alarm), shouldIconPulse: true, onTap:(){}, barBlur: 20, isDismissible: true, duration: Duration(seconds: 3), ); ////////// ALL FEATURES ////////// // Color colorText, // Duration duration, // SnackPosition snackPosition, // Widget titleText, // Widget messageText, // bool instantInit, // Widget icon, // bool shouldIconPulse, // double maxWidth, // EdgeInsets margin, // EdgeInsets padding, // double borderRadius, // Color borderColor, // double borderWidth, // Color backgroundColor, // Color leftBarIndicatorColor, // List boxShadows, // Gradient backgroundGradient, // TextButton mainButton, // OnTap onTap, // bool isDismissible, // bool showProgressIndicator, // AnimationController progressIndicatorController, // Color progressIndicatorBackgroundColor, // Animation progressIndicatorValueColor, // SnackStyle snackStyle, // Curve forwardAnimationCurve, // Curve reverseAnimationCurve, // Duration animationDuration, // double barBlur, // double overlayBlur, // Color overlayColor, // Form userInputForm /////////////////////////////////// ``` Если вы предпочитаете традиционный snackbar, или хотите настроить его с нуля, вы можете использовать `Get.rawSnackbar();` который предоставляет RAW API, на котором был построен Get.snackbar. ### Dialogs Чтобы открыть: ```dart Get.dialog(YourDialogWidget()); ``` Чтобы открыть диалог по умолчанию: ```dart Get.defaultDialog( onConfirm: () => print("Ok"), middleText: "Dialog made in 3 lines of code" ); ``` Вы также можете использовать Get.generalDialog вместо showGeneralDialog. Для всех других виджетов диалога Flutter, включая cupertino, вы можете использовать Get.overlayContext вместо контекста и открывать его в любом месте вашего кода. Для виджетов, которые не используют Overlay, вы можете использовать Get.context. Эти два контекста будут работать в 99% случаев для замены контекста вашего пользовательского интерфейса, за исключением случаев, когда наследуемый виджет используется без контекста навигации. ### BottomSheets Get.bottomSheet похож на showModalBottomSheet, но не требует контекста. ```dart Get.bottomSheet( Container( child: Wrap( children: [ ListTile( leading: Icon(Icons.music_note), title: Text('Music'), onTap: () {} ), ListTile( leading: Icon(Icons.videocam), title: Text('Video'), onTap: () {}, ), ], ), ) ); ``` ## Вложенная навигация Get сделал вложенную навигацию Flutter еще проще. Вам не нужен контекст, и вы найдёте свой стек навигации по Id. - ПРИМЕЧАНИЕ: Создание параллельных стеков навигации может быть опасным. В идеале не используйте NestedNavigators или используйте их редко. Если этого требует ваш проект, продолжайте, но имейте в виду, что хранение нескольких стеков навигации в памяти может быть не лучшим решением для потребления оперативной памяти. Смотрите как это просто: ```dart Navigator( key: Get.nestedKey(1), // create a key by index initialRoute: '/', onGenerateRoute: (settings) { if (settings.name == '/') { return GetPageRoute( page: () => Scaffold( appBar: AppBar( title: Text("Main"), ), body: Center( child: TextButton( color: Colors.blue, onPressed: () { Get.toNamed('/second', id:1); // navigate by your nested route by index }, child: Text("Go to second"), ), ), ), ); } else if (settings.name == '/second') { return GetPageRoute( page: () => Center( child: Scaffold( appBar: AppBar( title: Text("Main"), ), body: Center( child: Text("second") ), ), ), ); } } ), ```