- [Route Management](#route-management) - [Cara pakai](#cara-pakai) - [Navigasi tanpa named route](#navigasi-tanpa-named-route) - [Navigasi menggunakan named route](#navigasi-menggunakan-named-route) - [Mengirim data ke named route](#mengirim-data-ke-named-route) - [Tautan URL dinamis](#tautan-url-dinamis) - [Middleware](#middleware) - [Navigasi tanpa konteks](#navigasi-tanpa-konteks) - [SnackBar](#snackbar) - [Dialog](#dialog) - [BottomSheet](#bottomsheet) - [Navigasi Bersarang](#navigasi-bersarang) # Route Management Ini adalah penjelasan lengkap mengenai route management di GetX. ## Cara pakai Tambahkan ini kedalam pubspec.yaml anda: ```yaml dependencies: get: ``` Jika anda akan menggunakan route/snackbar/dialog/bottomsheet tanpa konteks, atau menggunakan high-level API dari Get, cukup tambahkan "Get" sebelum MaterialApp, mengubahnya menjadi GetMaterialApp, dan selamat menikmati! ```dart GetMaterialApp( // Sebelumnya: MaterialApp( home: MyHome(), ) ``` ## Navigasi tanpa named route Untuk pindah ke halaman baru: ```dart Get.to(NextScreen()); ``` Untuk menutup snackbar, dialog, bottomsheet, atau apapun yang normalnya anda tutup menggunakan Navigator.pop(context); ```dart Get.back(); ``` Untuk pergi ke halaman baru dan mencegah user kembali ke halaman sebelumnya (biasanya digunakan untuk SplashScreen, LoginScreen, dsb). ```dart Get.off(NextScreen()); ``` Untuk pergi ke halaman baru dan batalkan navigasi sebelumnya (berguna untuk shopping cart, polls, dan test). ```dart Get.offAll(NextScreen()); ``` Untuk pergi ke halaman baru dan menerima atau memperbarui data segera setelah anda kembali dari halaman tersebut: ```dart var data = await Get.to(Payment()); ``` pada halaman lain, kirim data ke halaman sebelumnya: ```dart Get.back(result: 'success'); ``` Lalu gunakan: contoh: ```dart if(data == 'success') madeAnything(); ``` Bukankah anda ingin mempelajari sintaks kami? Cukup ubah Navigator (uppercase) ke navigator (lowercase), dan anda akan mendapatkan semua fungsi standar navigasi, tanpa harus menggunakan konteks. Contoh: ```dart // Navigator bawaan Flutter Navigator.of(context).push( context, MaterialPageRoute( builder: (BuildContext context) { return HomePage(); }, ), ); // Get menggunakan sintaks Flutter tanpa membutuhkan konteks. navigator.push( MaterialPageRoute( builder: (_) { return HomePage(); }, ), ); // Sintaks Get (Lebih baik, tapi anda juga berhak untuk tidak setuju) Get.to(HomePage()); ``` ## Navigasi menggunakan named route - Jika anda lebih suka bernavigasi menggunakan namedRoutes, Get juga bisa melakukannya. Untuk pindah ke halaman nextScreen ```dart Get.toNamed("/NextScreen"); ``` Untuk pindah dan hapus halaman sebelumnya dari widget tree. ```dart Get.offNamed("/NextScreen"); ``` Untuk pindah dan hapus semua halaman sebelumnya dari widget tree. ```dart Get.offAllNamed("/NextScreen"); ``` Untuk mendifinisikan route, gunakan 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 ), ], ) ); } ``` Untuk menangani navigasi ke route yang tidak terdefinisi (404), anda bisa mendefinisikan sebuah halaman unknownRoute didalam GetMaterialApp. ```dart void main() { runApp( GetMaterialApp( unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()), initialRoute: '/', getPages: [ GetPage(name: '/', page: () => MyHomePage()), GetPage(name: '/second', page: () => Second()), ], ) ); } ``` ### Mengirim data ke named route Cukup kirim apa yang anda mau sebagai arguments. Get menerima apapun disitu, baik dalam bentuk String, Map, List atau bahkan instance dari sebuah Kelas. ```dart Get.toNamed("/NextScreen", arguments: 'Get is the best'); ``` di dalam kelas atau controller anda: ```dart print(Get.arguments); // keluaran: Get is the best ``` ### Tautan URL dinamis Get menawarkan tautan URL dinamis lebih lanjut sama seperti di Web. Para Web developer mungkin sudah menginginkan fitur ini di Flutter, dan mungkin juga sering melihat sebuah package menjanjikan fitur ini dan mengantarkan sintaks yang benar benar berbeda dari sebuah URL yang kita miliki di web, Get juga menyelesaikan masalah ini. ```dart Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo"); ``` didalam controller/bloc/stateful/stateless class anda: ```dart print(Get.parameters['id']); // keluaran: 354 print(Get.parameters['name']); // keluaran: Enzo ``` Anda juga bisa menerima NamedParameters dengan Get dengan mudah: ```dart void main() { runApp( GetMaterialApp( initialRoute: '/', getPages: [ GetPage( name: '/', page: () => MyHomePage(), ), GetPage( name: '/profile/', page: () => MyProfile(), ), // Anda bisa mendefinisikan halaman berbeda untuk routes dengan arguments, // dan yang lainnya tanpa arguments, namun untuk itu anda perlu slash '/' // pada route yang tidak menerima arguments seperti diatas. GetPage( name: '/profile/:user', page: () => UserProfile(), ), GetPage( name: '/third', page: () => Third(), transition: Transition.cupertino ), ], ) ); } ``` Kirim data ke named route ```dart Get.toNamed("/profile/34954"); ``` Pada halaman kedua, ambil data menggunakan parameter ```dart print(Get.parameters['user']); // keluaran: 34954 ``` atau kirim beberapa parameter seperti ini ```dart Get.toNamed("/profile/34954?flag=true"); ``` Pada layar kedua, ambil data berdasarkan parameter seperti biasanya ```dart print(Get.parameters['user']); print(Get.parameters['flag']); // keluaran: 34954 true ``` Dan sekarang, yang anda perlu lakukan adalah menggunakan Get.toNamed() untuk bernavigasi ke named route anda, tanpa konteks (anda bisa memanggil route secara langsung dari kelas BLoC atau Controller), dan ketika aplikasi anda di-compile di web, route anda akan muncul di url <3 ### Middleware Jika anda ingin me-listen sebuah Get event untuk melakukan sebuah action, anda bisa menggunakan routingCallback didalamnya. ```dart GetMaterialApp( routingCallback: (routing) { if(routing.current == '/second'){ openAds(); } } ) ``` Jika anda tidak menggunakan GetMaterialApp, anda bisa menggunakan API untuk mengaitkan Middleware observer secara manual. ```dart void main() { runApp( MaterialApp( onGenerateRoute: Router.generateRoute, initialRoute: "/", navigatorKey: Get.key, navigatorObservers: [ GetObserver(MiddleWare.observer), // Disini ], ), ); } ``` Membuat sebuah kelas Middleware ```dart class MiddleWare { static observer(Routing routing) { /// Anda bisa me-listen sebuah route, snackbar, dialog, dan bottomsheet disetiap halaman. /// Jika anda harus memasukkan salah satu dari 3 event tersebut secara langsung disini, /// anda perlu menyebutkan bahwa event tersebut != (tidak sama dengan) apa yang mau anda lakukan. if (routing.current == '/second' && !routing.isSnackbar) { Get.snackbar("Halo", "Anda sedang berada di route kedua"); } else if (routing.current =='/third'){ print('route terakhir dipanggil'); } } } ``` Sekarang, gunakan Get dalam kode anda: ```dart class First extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.add), onPressed: () { Get.snackbar("halo", "saya adalah snackbar modern"); }, ), title: Text('Halaman Pertama'), ), body: Center( child: ElevatedButton( child: Text('Pindah halaman'), 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("halo", "saya adalah snackbar modern"); }, ), title: Text('Halaman kedua'), ), body: Center( child: ElevatedButton( child: Text('Pindah halaman'), onPressed: () { Get.toNamed("/third"); }, ), ), ); } } class Third extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Halaman ketiga"), ), body: Center( child: ElevatedButton( onPressed: () { Get.back(); }, child: Text('Kembali!'), ), ), ); } } ``` ## Navigasi tanpa konteks ### SnackBar Untuk mendapatkan SnackBar sederhana dengan Flutter, anda harus mendapatkan konteks dari sebuah Scaffold, atau anda harus menggunakan GlobalKey yang dikaitkan pada Scaffold anda ```dart final snackBar = SnackBar( content: Text('Halo!'), action: SnackBarAction( label: 'Saya adalah snackbar tua yang jelek :(', onPressed: () {} ), ); // Temukan Scaffold didalam widget tree dan gunakan itu // untuk menampilkan snackbar Scaffold.of(context).showSnackBar(snackBar); ``` Dengan Get: ```dart Get.snackbar('Halo', 'Saya adalah snackbar modern'); ``` Dengan Get, yang anda butuhkan hanya memanggil Get.snackbar darimanapun di kode anda atau menyesuaikannya sesuka hati anda! ```dart Get.snackbar( "Halo, saya snackbar milik Get!", // judul "Sulit dipercaya! Saya menggunakan SnackBar tanpa konteks, tanpa boilerplate, tanpa Scaffold, ini benar benar keren!", // pesan icon: Icon(Icons.alarm), shouldIconPulse: true, onTap: () {}, barBlur: 20, isDismissible: true, duration: Duration(seconds: 3), ); ////////// SEMUA FITUR ////////// // 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 /////////////////////////////////// ``` Jika anda lebih menyukai snackbar tradisional, atau ingin menyesuaikannya sendiri dari awal, termasuk menambahkan hanya satu baris (Get.snackbar memanfaatkan title dan message yang diperlukan), anda bisa gunakan `Get.rawSnackbar();` yang akan menyediakan RAW API untuk Get.snackbar yang dibuat. ### Dialog Untuk membuka dialog: ```dart Get.dialog(YourDialogWidget()); ``` Untuk membuka default dialog: ```dart Get.defaultDialog( onConfirm: () => print("Ok"), middleText: "Dialog made in 3 lines of code" ); ``` Anda juga bisa menggunakan Get.generalDialog daripada showGeneralDialog. Untuk semua widget dialog di Flutter, termasuk cupertino, anda bisa menggunakan Get.overlayContext daripada context, dan membukanya darimanapun di kode anda. Untuk widget yang tidak menggunakan Overlay, anda bisa menggunakan Get.context. Kedua konteks akan bekerja dalam 99% kasus untuk me-replace konteks dari UI anda, kecuali untuk kasus dimana inheritedWidget digunakan tanpa konteks navigasi. ### BottomSheet Get.bottomSheet sama seperti showModalBottomSheet, tapi tidak membutuhkan konteks. ```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: () {}, ), ], ), ) ); ``` ## Navigasi Bersarang Get membuat navigasi bersarang milik Flutter menjadi lebih mudah. Anda tidak perlu konteks, dan anda akan menemukan stack navigasi melalui Id. - CATATAN: Membuat stack navigasi parallel bisa jadi berbahaya. Sebaiknya hindari penggunaan Navigasi Bersarang, atau gunakan dengan bijak. Jika proyek anda membutuhkannya, silahkan, tapi mohon di ingat bahwa menyimpan lebih dari satu navigation stack didalam memori mungkin bukan ide yang bagus untuk konsumsi RAM. Lihat betapa sederhananya ini: ```dart Navigator( key: Get.nestedKey(1), // buat sebuah key menggunakan 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); // pindah ke halaman bersarang anda menggunakan 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") ), ), ), ); } } ), ```