{"id":103,"date":"2025-10-03T04:08:15","date_gmt":"2025-10-03T04:08:15","guid":{"rendered":"https:\/\/infokand23.my.id\/2015\/?p=103"},"modified":"2025-10-05T22:12:43","modified_gmt":"2025-10-05T22:12:43","slug":"navigation-routing-multiple-screen","status":"publish","type":"post","link":"https:\/\/infokand23.my.id\/2015\/navigation-routing-multiple-screen\/","title":{"rendered":"Navigation &amp; Routing : Multiple Screen"},"content":{"rendered":"\n<p>Navigation atau Navigasi merupakan sebuah proses perpindahan halaman<br>(screen\/page) dari satu halaman ke halaman lain dalam sebuah aplikasi flutter. Misalkan perpindahan darihalaman login aplikasi ke halaman utama aplikasi ketika tombol login ditekan. Navigasi pada flutter menggunakan widget Navigator. Wiget navigator ini bekerja menggunakan konsep tumpukan (stack), Gambar berkut ini merupakan konsep dasar navigasi pada flutter. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"278\" height=\"278\" src=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-2-edited.png\" alt=\"\" class=\"wp-image-107\" srcset=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-2-edited.png 278w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-2-edited-150x150.png 150w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-2-edited-75x75.png 75w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/><figcaption class=\"wp-element-caption\"><em>Sumber:<\/em> Navigasi Pada Flutter \u2014 Baraja Coding, 2022;<\/figcaption><\/figure>\n\n\n\n<p>Gambar di atas menjelaskan bahwa halaman aplikasi flutter akan beradapa pada posisi dasar, pada contoh di atas ialah Screen1. Ketika akan berpindah ke halaman baru, flutter akan menggunakan perintah push sehingga halaman baru berada di atas rumpukan halaman sebelumnya. Pada contoh di atas, ketika menggunakan perintah push, Screen 2 berada di atas Screen 1. Nah setelah kita berada di Screen 2 dan ingin kembali ke Screen 1 kita cukup menggunakan perintah pop maka Screen 1 akan naik ke tumpukan paling atas.<\/p>\n\n\n\n<p>Setelah memahami konsep tumpukan pada flutter, pertanyaan selanjutnya ialah bagaimana cara memanggil sebuah halaman ? <\/p>\n\n\n\n<p>Pada flutter untuk memanggil sebuah halaman kita dapat menggunakan routing. Routing atau Rute ialah sebuah sistem yang digunakan untuk mendefinisikan dan mengelola routes dalam aplikasi. Jika kita mendefinisikan route maka ketika memanggil sebuah halaman kita cukup memanggil nama route tersebut. Hal ini mempermudah dalam mengelola route tanpa harus membuat instance baru setiap kali akan memanggil suatu halaman. <\/p>\n\n\n\n<p>Terdapat beberapa<strong> jenis routing pada flutter <\/strong>sebagai berikut; <\/p>\n\n\n\n<p><mark style=\"background-color:#ffd2dd\" class=\"has-inline-color has-black-color\">Navigator (Anonymous Routes)<\/mark><\/p>\n\n\n\n<p>Routing jenis navigator ini menampilkan halaman dengan konsep tumpukan menggunakan animasi transisi ketika berpindah halaman. Untuk berpindah ke halaman baru pada navigator kita menggunakan  BuildContext. <strong><code>BuildContext<\/code><\/strong> adalah \u201cpenanda lokasi\u201d suatu widget di dalam pohon widget (widget tree) Flutter. Seperti pembahasan sebelumnya, pada navigator untuk berpindah halaman kita juga menggunakan push() dan pop().<\/p>\n\n\n\n<p>contoh penggunaan Navigator pada method push dan pop <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>\/\/Method push<\/strong>\nCenter(\n  child: ElevatedButton(\n    onPressed: () {\n      Navigator.push(                \/\/ini untuk push \n        context,                     \/\/ini BuildContex milik home\n        MaterialPageRoute(builder: (context) =&gt; const ProductDetail()),   \/\/pada push kita mau menambahkan halaman baru ke tumpukan jadi kita harus menentukan halaman mana yang harus ditampilkan\n      );\n    },\n    child: const Text('Go to Product Detail'),\n  ),\n),\n\n\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>\/\/Method pop<\/strong>\nCenter(\n  child: ElevatedButton(\n    onPressed: () {\n      Navigator.pop(context),\n    },\n  child: const Text('Back to Product'),\n  ),\n),\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#ffd2dd\" class=\"has-inline-color has-black-color\">Named Routes <\/mark><\/p>\n\n\n\n<p>Name Routed ini ialah sebuah cara memberi nama unik (string) pada setiap halaman\/ routes di aplikasi flutter. Dengan begitu, ketika mau pindah halaman kita cukup memanggil nama rute itu, bukan langsung bikin instance class. Named Routes ini biasanya langsung kita definisikan di dalam MaterialApp (atau CupertinoApp kalau gaya iOS). Berikut contoh penggunaan NamedRoutes<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>\/\/Definisikan Routes pada MaterialApp<\/strong>\n\nreturn MaterialApp(\n  initialRoute: '\/',      \/\/ini artinya route utama, menentukan halaman pertama(default) yang akan ditampilkan saat aplikasi dijalankann\n\n  routes: {      \n    '\/': (context) => const Product(),  \/\/Mendefinisikan bahwa route utama mengarah ke widget Product().\n\n    '\/product_detail': (context) => const ProductDetail(), \/\/Mendefinisikan route dengan nama '\/product_detail'.\n  },\n);\n<\/code><\/pre>\n\n\n\n<p>Setelah mendefinisikan routesnya pada MaterialApp kita bisa tinggal panggil routenya seperti berikut :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>onPressed: () {\n  Navigator.pushNamed(context, '\/product_detail');   \n},\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#ffd2dd\" class=\"has-inline-color has-black-color\">Generated Routes <\/mark><\/p>\n\n\n\n<p>Generated Routes adalah cara dinamis untuk menangani navigasi di flutter. Jadi, dibanding kita nulis daftar routes secara statis di MaterialApp, kita bisa pakai fungsi callback(onGeneratedRoute) yang berfungsi untuk :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Membuat halaman sesuai permintaan user<\/li>\n\n\n\n<li>Bawa parameter (misal ID produk, username, dll)<\/li>\n\n\n\n<li>Menangani kalau route yang diminta tidak ada (eror)<\/li>\n<\/ol>\n\n\n\n<p>Jika dianalogikan website sebagai mall besar, generated routes itu seperti repsionis mall. Di mana kita bisa nanya sama repsionis toko baju A di mana, dan repsionis akan mengantarkan kita ke toko tersebut namun jika toko A tidak tersedia, maka repsionis akan bilang &#8220;Maaf toko tersebut tidak tersedia&#8221; (halaman error\/404). <\/p>\n\n\n\n<p>Kalo make routes biasa, itu seperti peta tetap di mall. Kita bisa pilih halaman utama (\/), halaman detail produk (\/product_detail). Tapi cuma itu aja yang kita ketahui dan disediakan, kalo kita nanya toko A di mana, maka di peta ga ada jadi kita akan bingung.<\/p>\n\n\n\n<p>Untuk memahami lebih lanjut bisa lihat implementasi berikut <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MaterialApp(\n  onGenerateRoute: (settings) {               <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">\/\/Ini fungsi callback yang dipanggil setiap kali user navigasi ke suatu rute dengan<\/mark>\n\n    if (settings.name == '\/detail') {   <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">\/\/Cek dulu apakah user mau ke halaman \/detail kalo iya proses blok ini.<\/mark>\n      final args = settings.arguments as Map;\n      return MaterialPageRoute(\n        builder: (context) => DetailPage(data: args&#91;'data']),\n      );\n    }\n    return MaterialPageRoute(builder: (context) => NotFoundPage());\n  },\n);\n<\/code><\/pre>\n\n\n\n<p>Setelah kita memahami routing mari kita memahami <strong>jenis-jenis method<\/strong> navigation<\/p>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color has-black-color\">Push dan Pop<\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Push - Menambahkan halaman baru\nNavigator.push(context, route);\n\n\/\/ Pop - Kembali ke halaman sebelumnya\nNavigator.pop(context);\n\n\/\/ Pop dengan mengirim data kembali\nNavigator.pop(context, 'data yang dikembalikan');\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color has-black-color\">Push Replacement<\/mark><\/p>\n\n\n\n<p>Mengganti halaman sekarang dengan halaman baru. Halaman sebelumnya <strong>dihapus<\/strong> dari stack, jadi nggak bisa balik lagi dengan tombol &#8220;back&#8221;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Mengganti halaman saat ini dengan halaman baru \nNavigator.pushReplacement(\n  context,\n  MaterialPageRoute(builder: (context) => LoginPage()),\n);\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color has-black-color\">Push and Remove Until<\/mark><\/p>\n\n\n\n<p>Mengganti halaman sekarang dengan halaman baru, <strong>dan menghapus semua halaman sebelumnya<\/strong> sampai kondisi tertentu. Kalau pakai <code>(route) => false<\/code>, berarti hapus semua.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Menghapus semua halaman sebelumnya\nNavigator.pushAndRemoveUntil(\n  context,\n  MaterialPageRoute(builder: (context) => HomePage()),\n  (route) => false, \/\/ Hapus semua\n);\n<\/code><\/pre>\n\n\n\n<p><strong>Cara Mengirim dan Menerima Data <\/strong><\/p>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color\">Mengirim data <\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Dengan constructor\nNavigator.push(\n  context,\n  MaterialPageRoute(\n    builder: (context) => DetailPage(id: 123, name: 'Masnoer'),\n  ),\n);\n\n\/\/ Dengan named routes dan arguments\nNavigator.pushNamed(\n  context,\n  '\/detail',\n  arguments: {'id': 123, 'name': 'Celly'},\n);\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color\">Menerima data dengan constructor <\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class DetailPage extends StatelessWidget {\n  final int id;\n  final String name;\n\n  DetailPage({required this.id, required this.name});\n\n  @override\n  Widget build(BuildContext context) {\n    \/\/ Atau ambil dari arguments\n    final args = ModalRoute.of(context)!.settings.arguments as Map;\n\n    return Scaffold(\n      appBar: AppBar(title: Text('Detail: $name')),\n      body: Text('ID: $id'),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:#f78da7\" class=\"has-inline-color\">Menerima data Menggunakan ModalRoute.of(context)<\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class DetailPage extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    \/\/ Ambil arguments dari route\n    final args = ModalRoute.of(context)!.settings.arguments as Map;\n\n    \/\/ Akses data\n    final int id = args&#91;'id'];\n    final String name = args&#91;'name'];\n\n    return Scaffold(\n      appBar: AppBar(title: Text('Detail Page')),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: &#91;\n            Text('ID: $id', style: TextStyle(fontSize: 20)),\n            Text('Name: $name', style: TextStyle(fontSize: 20)),\n          ],\n        ),\n      ),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Setelah memahami beberapa hal di atas kita akan coba melakukan implementasi di program.<\/p>\n\n\n\n<p>A. Multiple Screen<\/p>\n\n\n\n<p>Berikut kode program lengkap untuk navigation dan routing<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyNav());\n\nclass MyNav extends StatelessWidget {\n  const MyNav({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: '\/',\n      routes: {\n        '\/': (context) => const Product(),\n        '\/product_detail': (context) => const ProductDetail(),\n      },\n    );\n  }\n}\n\n\n\/\/BIKIN CLASS PRODUCT \nclass Product extends StatelessWidget {\n  const Product({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Product'),\n      ),\n      body: Center(\n        child: ElevatedButton(\n          onPressed: () {\n            Navigator.pushNamed(context, '\/product_detail');  \/\/memanggil halaman product detail\n          },\n          child: const Text('Go to product detail'),\n        ),\n      ),\n    );\n  }\n}\n\nclass ProductDetail extends StatelessWidget {\n  const ProductDetail({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Product Detail'),\n      ),\n      body: Center(\n        child: ElevatedButton(\n          onPressed: () {\n            Navigator.pop(context);\n          },\n          child: const Text('Back to product'),\n        ),\n      ),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>B. Mengirim dan Menerima Data<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      debugShowCheckedModeBanner: false,\n      initialRoute: '\/',\n      routes: {       \/\/make route di initialapp\n        '\/': (context) => const HomePage(),\n        '\/product': (context) => const MyProduct(),\n      },\n    );\n  }\n}\n\n\n\/\/CLASS HOMEPACKED \nclass HomePage extends StatelessWidget {\n  const HomePage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Home Page'),\n      ),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: &#91;\n            \/\/ Kirim data lewat Constructor\n            ElevatedButton(\n              onPressed: () {\n                Navigator.push(     \/\/pushnya menambahkan halaman baru \n                  context,\n                  MaterialPageRoute(\n                    builder: (context) =>  \/\/generated routes \n                        const MyProfile(id: 1, name: 'Sherly'),    \/\/ini tu make namerute\n                  ),\n                );\n              },\n              child: const Text('Profile'),\n            ),\n\n            const SizedBox(height: 20),\n\n            \/\/ Kirim data lewat Named Routes + arguments\n            ElevatedButton(\n              onPressed: () {\n                Navigator.pushNamed(\n                  context,\n                  '\/product',\n                  arguments: {'id': 101, 'name': 'Laptop'},\n                );\n              },\n              child: const Text('Product'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n\n\/\/ ============ PROFILE PAGE (terima data lewat Constructor) ============\nclass MyProfile extends StatelessWidget {\n  final int id;\n  final String name;\n\n  const MyProfile({super.key, required this.id, required this.name});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Profile'),\n      ),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: &#91;\n            Text('ID: $id'),\n            Text('Name: $name'),\n          ],\n        ),\n      ),\n    );\n  }\n}\n\n\/\/ ============ PRODUCT PAGE (terima data lewat ModalRoute) ============\nclass MyProduct extends StatelessWidget {\n  const MyProduct({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    \/\/ Ambil arguments yang dikirim dari HomePage\n    final args =\n        ModalRoute.of(context)!.settings.arguments as Map&lt;String, dynamic>?;\n\n    final int id = args?&#91;'id'] ?? 0;\n    final String name = args?&#91;'name'] ?? 'Unknown';\n\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Product'),\n      ),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: &#91;\n            Text('Product ID: $id'),\n            Text('Product Name: $name'),\n          ],\n        ),\n      ),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>C. Tugas 1<\/p>\n\n\n\n<p>Buatlah halaman login dan halaman utama, kemudian inputkan username dan password,<br>Ketika diklik login akan berpindah ke halaman utama dengan mengirimkan data username<br>dan password, tampilkan data tersebut pada halaman utama.<\/p>\n\n\n\n<p>Jawab :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'Tugas Login',\n      debugShowCheckedModeBanner: false,\n      initialRoute: '\/login',\n      onGenerateRoute: (settings) {\n        if (settings.name == '\/home') {\n          \/\/ ambil data dari arguments\n          final args = settings.arguments as Map&lt;String, String>;\n          return MaterialPageRoute(\n            builder: (context) => HomePage(\n              username: args&#91;'username']!,\n              password: args&#91;'password']!,\n            ),\n          );\n        }\n        \/\/ default route = login\n        return MaterialPageRoute(builder: (context) => const LoginPage());\n      },\n    );\n  }\n}\n\n\/\/ =================== HALAMAN LOGIN ===================\n\nclass LoginPage extends StatefulWidget {\n  const LoginPage({super.key});\n\n  @override\n  _LoginPageState createState() => _LoginPageState();\n}\n\nclass _LoginPageState extends State&lt;LoginPage> {\n  final _formKey = GlobalKey&lt;FormState>();\n  String _username = '';\n  String _password = '';\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Login')),\n      body: Padding(\n        padding: const EdgeInsets.all(16.0),\n        child: Form(\n          key: _formKey,\n          child: Column(\n            mainAxisAlignment: MainAxisAlignment.center,\n            children: &#91;\n              TextFormField(\n                decoration: const InputDecoration(\n                  labelText: 'Username',\n                  border: OutlineInputBorder(),\n                ),\n                validator: (value) =>\n                    value == null || value.isEmpty ? 'Enter username' : null,\n                onSaved: (value) => _username = value!,\n              ),\n              const SizedBox(height: 16),\n              TextFormField(\n                decoration: const InputDecoration(\n                  labelText: 'Password',\n                  border: OutlineInputBorder(),\n                ),\n                obscureText: true,\n                validator: (value) =>\n                    value == null || value.isEmpty ? 'Enter password' : null,\n                onSaved: (value) => _password = value!,\n              ),\n              const SizedBox(height: 16),\n              ElevatedButton(\n                onPressed: () {\n                  if (_formKey.currentState!.validate()) {\n                    _formKey.currentState!.save();\n\n                    \/\/ Navigasi ke halaman utama dengan data\n                    Navigator.pushNamed(\n                      context,\n                      '\/home',\n                      arguments: {\n                        'username': _username,\n                        'password': _password,\n                      },\n                    );\n                  }\n                },\n                child: const Text('Login'),\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n\n\n\nclass HomePage extends StatelessWidget {\n  final String username;\n  final String password;\n\n  const HomePage({super.key, required this.username, required this.password});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Halaman Utama')),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: &#91;\n            Text('Username: $username', style: const TextStyle(fontSize: 20)),\n            Text('Password: $password', style: const TextStyle(fontSize: 20)),\n          ],\n        ),\n      ),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-1024x576.png\" alt=\"\" class=\"wp-image-110\" srcset=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-1024x576.png 1024w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-300x169.png 300w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-768x432.png 768w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-1536x864.png 1536w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3-1140x641.png 1140w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-3.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-1024x576.png\" alt=\"\" class=\"wp-image-111\" srcset=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-1024x576.png 1024w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-300x169.png 300w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-768x432.png 768w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-1536x864.png 1536w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4-1140x641.png 1140w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-4.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>D. Tugas 2<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'package:flutter\/material.dart';\n\nvoid main() {\n  runApp(MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: HomePage(),\n    );\n  }\n}\n\nclass HomePage extends StatefulWidget {\n  @override\n  _HomePageState createState() => _HomePageState();\n}\n\nclass _HomePageState extends State&lt;HomePage> {\n  int _selectedIndex = 0;\n\n  \/\/ Daftar halaman (pakai class terpisah)\n  final List&lt;Widget> _pages = &#91;\n    HomeScreen(),\n    SearchScreen(),\n    ProfileScreen(),\n  ];\n\n  void _onItemTapped(int index) {\n    setState(() {\n      _selectedIndex = index;\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: Text(\"Contoh Bottom Navigation\")),\n      body: _pages&#91;_selectedIndex], \/\/ halaman berubah sesuai index\n      bottomNavigationBar: BottomNavigationBar(\n        currentIndex: _selectedIndex,\n        onTap: _onItemTapped,\n        items: const &#91;\n          BottomNavigationBarItem(\n            icon: Icon(Icons.home),\n            label: 'Home',\n          ),\n          BottomNavigationBarItem(\n            icon: Icon(Icons.search),\n            label: 'Search',\n          ),\n          BottomNavigationBarItem(\n            icon: Icon(Icons.person),\n            label: 'Profile',\n          ),\n        ],\n      ),\n    );\n  }\n}\n\n\/\/ \ud83d\udd39 Halaman Home\nclass HomeScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text('Ini Halaman Home', style: TextStyle(fontSize: 24)),\n    );\n  }\n}\n\n\/\/ \ud83d\udd39 Halaman Search\nclass SearchScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text('Ini Halaman Search', style: TextStyle(fontSize: 24)),\n    );\n  }\n}\n\n\/\/ \ud83d\udd39 Halaman Profile\nclass ProfileScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text('Ini Halaman Profile', style: TextStyle(fontSize: 24)),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-1024x576.png\" alt=\"\" class=\"wp-image-112\" srcset=\"https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-1024x576.png 1024w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-300x169.png 300w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-768x432.png 768w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-1536x864.png 1536w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5-1140x641.png 1140w, https:\/\/infokand23.my.id\/2015\/wp-content\/uploads\/2025\/10\/image-5.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Navigation atau Navigasi merupakan sebuah proses perpindahan halaman(screen\/page) dari satu halaman ke halaman lain dalam sebuah aplikasi flutter. Misalkan perpindahan darihalaman login aplikasi ke halaman utama aplikasi ketika tombol login ditekan. Navigasi pada flutter menggunakan widget Navigator. Wiget navigator ini bekerja menggunakan konsep tumpukan (stack), Gambar berkut ini merupakan konsep dasar navigasi pada flutter. Gambar di atas menjelaskan bahwa halaman aplikasi flutter akan beradapa pada posisi dasar, pada contoh di atas ialah Screen1. Ketika akan berpindah ke halaman baru, flutter akan menggunakan perintah push sehingga halaman baru berada di atas rumpukan halaman sebelumnya. Pada contoh di atas, ketika menggunakan perintah push, Screen 2 berada di atas Screen 1. Nah setelah kita berada di Screen 2 dan ingin kembali ke Screen 1 kita cukup menggunakan perintah pop maka Screen 1 akan naik ke tumpukan paling atas. Setelah memahami konsep tumpukan pada flutter, pertanyaan selanjutnya ialah bagaimana cara memanggil sebuah halaman ? Pada flutter untuk memanggil sebuah halaman kita dapat menggunakan routing. Routing atau Rute ialah sebuah sistem yang digunakan untuk mendefinisikan dan mengelola routes dalam aplikasi. Jika kita mendefinisikan route maka ketika memanggil sebuah halaman kita cukup memanggil nama route tersebut. Hal ini mempermudah dalam mengelola route tanpa harus membuat instance baru setiap kali akan memanggil suatu halaman. Terdapat beberapa jenis routing pada flutter sebagai berikut; Navigator (Anonymous Routes) Routing jenis navigator ini menampilkan halaman dengan konsep tumpukan menggunakan animasi transisi ketika berpindah halaman. Untuk berpindah ke halaman baru pada navigator kita menggunakan BuildContext. BuildContext adalah \u201cpenanda lokasi\u201d suatu widget di dalam pohon widget (widget tree) Flutter. Seperti pembahasan sebelumnya, pada navigator untuk berpindah halaman kita juga menggunakan push() dan pop(). contoh penggunaan Navigator pada method push dan pop Named Routes Name Routed ini ialah sebuah cara memberi nama unik (string) pada setiap halaman\/ routes di aplikasi flutter. Dengan begitu, ketika mau pindah halaman kita cukup memanggil nama rute itu, bukan langsung bikin instance class. Named Routes ini biasanya langsung kita definisikan di dalam MaterialApp (atau CupertinoApp kalau gaya iOS). Berikut contoh penggunaan NamedRoutes Setelah mendefinisikan routesnya pada MaterialApp kita bisa tinggal panggil routenya seperti berikut : Generated Routes Generated Routes adalah cara dinamis untuk menangani navigasi di flutter. Jadi, dibanding kita nulis daftar routes secara statis di MaterialApp, kita bisa pakai fungsi callback(onGeneratedRoute) yang berfungsi untuk : Jika dianalogikan website sebagai mall besar, generated routes itu seperti repsionis mall. Di mana kita bisa nanya sama repsionis toko baju A di mana, dan repsionis akan mengantarkan kita ke toko tersebut namun jika toko A tidak tersedia, maka repsionis akan bilang &#8220;Maaf toko tersebut tidak tersedia&#8221; (halaman error\/404). Kalo make routes biasa, itu seperti peta tetap di mall. Kita bisa pilih halaman utama (\/), halaman detail produk (\/product_detail). Tapi cuma itu aja yang kita ketahui dan disediakan, kalo kita nanya toko A di mana, maka di peta ga ada jadi kita akan bingung. Untuk memahami lebih lanjut bisa lihat implementasi berikut Setelah kita memahami routing mari kita memahami jenis-jenis method navigation Push dan Pop Push Replacement Mengganti halaman sekarang dengan halaman baru. Halaman sebelumnya dihapus dari stack, jadi nggak bisa balik lagi dengan tombol &#8220;back&#8221;. Push and Remove Until Mengganti halaman sekarang dengan halaman baru, dan menghapus semua halaman sebelumnya sampai kondisi tertentu. Kalau pakai (route) => false, berarti hapus semua. Cara Mengirim dan Menerima Data Mengirim data Menerima data dengan constructor Menerima data Menggunakan ModalRoute.of(context) Setelah memahami beberapa hal di atas kita akan coba melakukan implementasi di program. A. Multiple Screen Berikut kode program lengkap untuk navigation dan routing B. Mengirim dan Menerima Data C. Tugas 1 Buatlah halaman login dan halaman utama, kemudian inputkan username dan password,Ketika diklik login akan berpindah ke halaman utama dengan mengirimkan data usernamedan password, tampilkan data tersebut pada halaman utama. Jawab : D. Tugas 2<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-103","post","type-post","status-publish","format-standard","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/posts\/103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/comments?post=103"}],"version-history":[{"count":3,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/posts\/103\/revisions"}],"predecessor-version":[{"id":113,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/posts\/103\/revisions\/113"}],"wp:attachment":[{"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/media?parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/categories?post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infokand23.my.id\/2015\/wp-json\/wp\/v2\/tags?post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}