01 / 23
8
Β»
↦
ↀ
‴
‡
BAB 8 Β· MODUL INTERAKTIF

Navigation & Routing

Belajar bagaimana aplikasi Flutter berpindah halaman β€” membuka layar baru, kembali, mengirim & menerima data, hingga membangun aplikasi banyak halaman.

Kelas 10–11 Semester 1 Flutter 3.x / Dart 3.x 23 Slide

Gunakan ← β†’ pada keyboard atau tombol di bawah untuk berpindah slide.

02Tujuan Pembelajaran

Apa yang akan kamu kuasai

Setelah menyelesaikan BAB 8, kamu diharapkan mampu mencapai 6 tujuan berikut. Di sisi kanan, lihat peta konsep yang menghubungkan seluruh materi bab ini.

🎯 6 Tujuan Pembelajaran

  1. 1
    Memahami Navigation Stack

    Menjelaskan konsep tumpukan halaman & prinsip LIFO dengan kata-kata sendiri.

  2. 2
    Menguasai push & pop

    Menulis Navigator.push() & Navigator.pop() tanpa referensi (target 80% akurat).

  3. 3
    Memakai Named Route

    Mendaftarkan minimal 3 named route di MaterialApp dan menavigasinya.

  4. 4
    Mengirim data (Passing Data)

    Mengirim objek data dari halaman list ke detail lewat constructor.

  5. 5
    Menerima data (Return Data)

    Menerima data balik dari sub-halaman dengan async/await.

  6. 6
    Membangun Mini Project

    Membuat aplikasi Katalog Produk 3 halaman yang berfungsi penuh.

πŸ—ΊοΈ Peta Konsep BAB 8

Semua topik bermuara pada satu inti: Navigation.

NAVIGATION
🧭 Navigator
⬆ push()
⬇ pop()
🏷️ Named Route
βœ‰ Passing Data
↩ Return Data
πŸ“š Multi Page App
πŸ›οΈ Mini Project
Pola belajar: setiap topik disajikan berurutan β†’ Konsep β†’ Analogi β†’ Penjelasan β†’ Kode β†’ Demo. Ikuti slide secara berurutan agar mudah dipahami.

03Jembatan: BAB 7 β†’ BAB 8

Dari satu layar ke banyak layar

Di BAB 7 kamu sudah belajar membuat Form & Input β€” pengguna mengisi nama, email, lalu menekan tombol Submit. Tapi semuanya masih terjadi di satu halaman saja. Pertanyaan pemantiknya:

❓ "Setelah menekan tombol, bagaimana caranya aplikasi berpindah ke halaman berikutnya?"
1

BAB 4–6 Β· Membangun Layar

Kamu belajar Widget, Layout, dan menyusun tampilan satu halaman.

2

BAB 7 Β· Interaksi Input

Pengguna mengisi form dan menekan tombol β€” tapi masih di layar yang sama.

3

BAB 8 Β· Berpindah Halaman πŸš€

Kini kita pelajari cara membuka layar baru, kembali, dan mengirim data antar halaman.

Hampir semua aplikasi nyata (Instagram, Shopee, Gojek) terdiri dari puluhan halaman. Kemampuan berpindah halaman adalah jantung dari aplikasi mobile yang sesungguhnya.

04Apa itu Navigation?

Konsep berpindah antar halaman

Navigation (navigasi) adalah proses berpindah dari satu halaman/layar ke halaman lain di dalam sebuah aplikasi. Di Flutter, setiap halaman disebut route (rute), dan yang mengatur perpindahan ini adalah widget bernama Navigator.

Bayangkan sebuah GEDUNG BERTINGKAT. Setiap lantai adalah satu halaman aplikasi. Untuk berpindah lantai, kamu naik LIFT. Nah, lift itulah Navigator β€” alat yang membawamu dari satu lantai (halaman) ke lantai lain.

Koneksi ke Flutter: Lantai = route/halaman. Lift = Navigator. Naik ke lantai atas = push (buka halaman baru). Turun ke lantai sebelumnya = pop (kembali).

🏒 Gedung = Aplikasi

Lantai 1 Β· Home route /
Lantai 2 Β· Detail /detail
Lantai 3 Β· Profil /profil
Lantai 4 Β· Setting /setting
LIFT
Navigator

naik = push
turun = pop

05Navigation Stack & Prinsip LIFO

Tumpukan halaman

Flutter menyimpan halaman-halaman yang sedang terbuka dalam sebuah tumpukan (stack). Prinsipnya adalah LIFO β€” Last In, First Out (yang terakhir masuk, yang pertama keluar).

Seperti tumpukan nampan di kantin sekolah. Nampan baru selalu ditaruh di paling atas (PUSH). Saat mengambil, kamu juga mengambil dari paling atas dulu (POP). Nampan paling bawah keluar paling terakhir.

Koneksi ke Flutter: PUSH = menaruh halaman baru di atas tumpukan (halaman ini yang tampil). POP = mengangkat halaman teratas, sehingga halaman di bawahnya muncul kembali.
AksiEfek pada Stack
push(Home)[Home]
push(Detail)[Home, Detail]
push(Profil)[Home, Detail, Profil]
pop()[Home, Detail] ← Profil terangkat

🍽️ Tumpukan Nampan (LIFO)

Halaman 1 (Home)
Halaman 2 (Detail)
Halaman 3 (Profil)

PUSH muncul dari bawah, POP menghilang ke atas

06Navigator Widget

Sang penjaga tumpukan halaman

Navigator adalah widget khusus yang mengelola stack halaman. Kabar baiknya: saat kamu memakai MaterialApp, sebuah Navigator sudah otomatis tersedia di atas widget tree-mu. Jadi kamu tinggal memanggilnya lewat Navigator.of(context) atau cara singkat Navigator.push(...).

Navigator ibarat petugas resepsionis hotel yang memegang daftar tamu (stack). Dialah yang tahu kamu sedang di kamar mana dan ke mana kamu boleh pindah.

Posisi di Widget Tree: MaterialApp β†’ Navigator (otomatis) β†’ Halaman aktif. Karena Navigator berada di atas semua halaman, halaman manapun bisa memanggilnya melalui BuildContext.
void main() { runApp(const MyApp()); // jalankan aplikasi } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( // MaterialApp menyediakan Navigator otomatis home: const HalamanHome(), // halaman pertama di tumpukan ); } }
β–Ά Output: Aplikasi terbuka langsung menampilkan HalamanHome sebagai dasar tumpukan navigasi.

07Navigator.push()

Membuka halaman baru

Navigator.push() dipakai untuk membuka/menumpuk halaman baru di atas halaman sekarang.

Seperti membuka pintu dan masuk ke ruangan baru. Ruangan lama masih ada di belakangmu β€” kamu tinggal masuk ke ruangan berikutnya.

Koneksi: Pintu terbuka = halaman baru muncul di layar. Ruangan lama (halaman sebelumnya) tetap tersimpan di stack, siap kamu kembali nanti.
// Saat tombol ditekan, buka HalamanDetail ElevatedButton( onPressed: () { Navigator.push( // menumpuk halaman baru context, // konteks halaman sekarang MaterialPageRoute( // pembungkus rute + animasi builder: (context) => const HalamanDetail(), // tujuan ), ); }, child: const Text('Buka Detail'), )
β–Ά Output: Layar bertransisi (geser) ke HalamanDetail. Muncul tombol "back" otomatis di AppBar.

08Navigator.pop()

Kembali ke halaman sebelumnya

Navigator.pop() dipakai untuk menutup halaman teratas dan kembali ke halaman di bawahnya.

Seperti keluar dari ruangan dan menutup pintu. Kamu kembali ke ruangan sebelumnya yang tadi kamu tinggalkan.

Koneksi: Pintu tertutup = halaman teratas diangkat dari stack. Halaman sebelumnya muncul lagi persis seperti saat kamu tinggalkan.
// Di dalam HalamanDetail β€” tombol kembali ElevatedButton( onPressed: () { Navigator.pop(context); // angkat halaman teratas }, child: const Text('Kembali'), ) // Catatan: tombol back AppBar & tombol // back HP juga otomatis memanggil pop()
β–Ά Output: HalamanDetail tertutup, layar kembali ke halaman sebelumnya (mis. HalamanHome).
Hati-hati: Jika kamu pop pada halaman paling dasar (satu-satunya di stack), aplikasi bisa keluar/blank. Selalu pastikan ada halaman di bawahnya.

09Push vs Pop β€” Perbandingan

Dua aksi, arah berlawanan

⬆ PUSH

Menambah halaman baru ke atas tumpukan.

Masuk ruanganMajuStack bertambah
Navigator.push(context, route);

⬇ POP

Mengangkat halaman teratas dari tumpukan.

Keluar ruanganMundurStack berkurang
Navigator.pop(context);
Aspekpush()pop()
TujuanBuka halaman baruKembali ke halaman lama
Efek stack+1 halamanβˆ’1 halaman
Argumen utamacontext + Routecontext (+ data opsional)
Tombol back AppBarMuncul otomatisYang dipicu saat ditekan
Analogi pintuPintu terbuka, masukPintu tertutup, keluar

10Named Routes

Rute dengan nama

Daripada menulis MaterialPageRoute berulang-ulang, kita bisa memberi setiap halaman sebuah nama/alamat (misalnya '/detail'). Ini disebut Named Route. Navigasi jadi lebih rapi dan mudah dikelola untuk aplikasi besar.

Seperti nama jalan di sebuah kota. Daripada menjelaskan "rumah ketiga setelah belokan", kamu cukup sebut alamatnya: "Jl. Merdeka No. 10". Setiap tempat punya nama unik.

Koneksi: Nama jalan = nama route (string). Kamu cukup berkata "antar saya ke /profil" dan Navigator tahu halaman mana yang dimaksud.

Titik biru bergerak = pengguna berpindah dari satu "alamat" ke alamat lain mengikuti nama route.

11Mendaftarkan Named Routes

Properti routes di MaterialApp

Semua nama route didaftarkan dalam properti routes: { } milik MaterialApp. Bentuknya adalah Map: kuncinya nama route (String), nilainya fungsi yang membangun halaman.

MaterialApp( initialRoute: '/', // route yang pertama dibuka routes: { // daftar semua halaman bernama '/': (context) => const HalamanHome(), // alamat home '/detail': (context) => const HalamanDetail(), // alamat detail '/profil': (context) => const HalamanProfil(), // alamat profil }, )
1

initialRoute

Menentukan halaman pertama yang tampil saat aplikasi dibuka (di sini '/').

2

routes (Map)

Pasangan nama β†’ builder halaman. Tambah baris baru untuk setiap halaman baru.

3

Konsisten

Gunakan nama yang jelas dan diawali garis miring, mis. '/keranjang', '/checkout'.

β–Ά Output: Tiga halaman kini terdaftar dengan alamat. Aplikasi siap dinavigasi memakai pushNamed().

12Navigator.pushNamed()

Navigasi memakai nama route

Setelah route didaftarkan, cukup panggil Navigator.pushNamed() dengan nama route tujuan. Jauh lebih singkat!

// Pindah ke halaman detail lewat namanya ElevatedButton( onPressed: () { Navigator.pushNamed( context, '/detail', // cukup sebut alamatnya ); }, child: const Text('Ke Detail'), )
β–Ά Output: Aplikasi berpindah ke HalamanDetail tanpa perlu menulis MaterialPageRoute lagi.

⚠️ Error Handling β€” route tidak ada

Jika kamu memanggil nama route yang belum didaftarkan, aplikasi akan error. Sediakan onUnknownRoute sebagai pengaman:

MaterialApp( routes: { /* ... */ }, onUnknownRoute: (settings) { // jika route tak dikenal return MaterialPageRoute( builder: (_) => const Halaman404(), ); }, )
Tips: Selalu pastikan nama route yang dipanggil sama persis dengan yang didaftarkan (huruf besar/kecil berpengaruh).

13Passing Data

Mengirim data ke halaman tujuan

Sering kali halaman baru butuh data dari halaman sebelumnya β€” misal halaman detail butuh tahu produk mana yang diklik. Cara paling umum: kirim data lewat constructor halaman tujuan.

Seperti mengirim amplop berisi pesan ke alamat tujuan. Isi amplop (data) dibawa langsung ke penerima (halaman tujuan).

🏠
πŸ“„
// 1) Halaman tujuan menerima data lewat constructor class HalamanDetail extends StatelessWidget { final String namaProduk; // data yang diterima const HalamanDetail({super.key, required this.namaProduk}); @override Widget build(BuildContext context) { return Text(namaProduk); // pakai datanya } } // 2) Halaman asal mengirim data Navigator.push(context, MaterialPageRoute( builder: (_) => const HalamanDetail( namaProduk: 'Sepatu Lari', // isi amplopnya ), ));
β–Ά Output: HalamanDetail tampil dan menampilkan teks "Sepatu Lari".

14Return Data

Menerima data balik dari sub-halaman

Kadang halaman tujuan harus mengembalikan hasil ke halaman asal β€” misal halaman "Pilih Warna" mengembalikan warna yang dipilih. Caranya: kirim data lewat Navigator.pop(hasil), lalu tangkap dengan async/await.

Seperti balasan surat atau laporan tugas yang dikembalikan guru. Kamu kirim surat (push), lalu menunggu balasannya (await) sebelum melanjutkan.

🏠
🎨
// 1) Halaman asal: tunggu hasil dengan await onPressed: () async { // fungsi async final hasil = await Navigator.push( context, MaterialPageRoute( builder: (_) => const HalamanPilihWarna(), ), ); print('Warna dipilih: $hasil'); // pakai hasilnya } // 2) Sub-halaman: kembalikan data lewat pop Navigator.pop(context, 'Merah'); // kirim balik 'Merah'
β–Ά Output (console): Warna dipilih: Merah
Inti: await membuat aplikasi "menunggu" sampai sub-halaman ditutup, lalu nilai dari pop() menjadi isi variabel hasil.

15Simulator Navigation Stack

Coba sendiri β€” interaktif!

Klik tombol PUSH untuk menumpuk halaman baru, dan POP untuk mengangkat halaman teratas. Perhatikan bagaimana tumpukan berubah sesuai prinsip LIFO.

⬇ Dasar Stack (Home selalu di paling bawah)
Stack: [Home]
Jumlah halaman: 1

Yang terakhir di-push akan jadi yang pertama di-pop (LIFO).

16Multi Page App

Arsitektur aplikasi banyak halaman

Aplikasi nyata terdiri dari banyak halaman yang saling terhubung. Multi Page App adalah pola di mana kamu menyusun beberapa halaman, mendaftarkannya sebagai route, lalu mengatur alur navigasi di antara mereka.

Seperti sebuah buku dengan banyak halaman dan daftar isi. Daftar isi (routes) memberi tahu di mana setiap halaman berada, dan kamu bisa lompat ke halaman manapun.

πŸ—ΊοΈ Flowchart Struktur Aplikasi

A

main.dart

Titik awal. Berisi MaterialApp + daftar routes + initialRoute.

B

Halaman Home (List)

Menampilkan daftar item. Setiap item β†’ pushNamed('/detail') sambil mengirim data.

C

Halaman Detail

Menerima data dari Home, menampilkannya. Tombol kembali β†’ pop().

D

Halaman Tambahan

Profil, Keranjang, dsb. Semua terdaftar di routes dan saling terhubung lewat Navigator.

Kunci aplikasi multi-halaman yang rapi: pisahkan tiap halaman ke widget/class sendiri, daftarkan di routes, dan gunakan passing data untuk komunikasi antar halaman.

17Mini Project: Katalog Produk

Wireframe & alur navigasi

Saatnya menggabungkan semua! Kita akan membangun Aplikasi Katalog Produk dengan 2 halaman utama: Daftar Produk dan Detail Produk. Saat produk diklik, datanya dikirim ke halaman detail.

πŸ›οΈ Katalog
Sepatu Lari
Rp 250.000
lihat β€Ί
Tas Ransel
Rp 180.000
lihat β€Ί
Topi Sport
Rp 75.000
lihat β€Ί
➑

Klik produk β†’
kirim data via constructor β†’
Navigator.push

β¬…

Tombol kembali β†’
Navigator.pop

β€Ή Detail
πŸ‘Ÿ

Sepatu Lari

Rp 250.000

Sepatu ringan untuk lari pagi, nyaman & awet.

β€Ή Kembali

Pada slide berikutnya kita tulis kodenya bertahap: Bagian 1 (main + daftar) lalu Bagian 2 (detail + passing data).

18Mini Project β€” Kode Bagian 1

main.dart + model + halaman daftar
import 'package:flutter/material.dart'; // Model sederhana untuk satu produk class Produk { final String nama; final int harga; final String emoji; const Produk(this.nama, this.harga, this.emoji); } void main() => runApp(const KatalogApp()); class KatalogApp extends StatelessWidget { const KatalogApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Katalog Produk', home: const HalamanDaftar(), // halaman pertama ); } } class HalamanDaftar extends StatelessWidget { const HalamanDaftar({super.key}); @override Widget build(BuildContext context) { final produkList = [ // data contoh const Produk('Sepatu Lari', 250000, 'πŸ‘Ÿ'), const Produk('Tas Ransel', 180000, 'πŸŽ’'), const Produk('Topi Sport', 75000, '🧒'), ]; return Scaffold( appBar: AppBar(title: const Text('Katalog Produk')), body: ListView.builder( itemCount: produkList.length, itemBuilder: (context, i) { final p = produkList[i]; return ListTile( leading: Text(p.emoji, style: const TextStyle(fontSize: 28)), title: Text(p.nama), subtitle: Text('Rp ${p.harga}'), onTap: () { // saat produk diklik Navigator.push(context, MaterialPageRoute( builder: (_) => HalamanDetail(produk: p), // kirim data )); }, ); }, ), ); } }
β–Ά Output: Muncul daftar 3 produk. Mengetuk salah satu akan membuka halaman detailnya (kode Bagian 2).

19Mini Project β€” Kode Bagian 2

Halaman detail + passing data
// Halaman detail menerima objek Produk class HalamanDetail extends StatelessWidget { final Produk produk; // data dari halaman daftar const HalamanDetail({ super.key, required this.produk, }); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(produk.nama)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(produk.emoji, style: const TextStyle(fontSize: 80)), Text(produk.nama, style: const TextStyle(fontSize: 24)), Text('Rp ${produk.harga}'), const SizedBox(height: 20), ElevatedButton( onPressed: () => Navigator.pop(context), child: const Text('Kembali'), ), ], ), ), ); } }

πŸ“± Preview Hasil Akhir

β€Ή Sepatu Lari
πŸ‘Ÿ

Sepatu Lari

Rp 250000

Kembali
β–Ά Alur lengkap: Daftar β†’ ketuk produk β†’ push + kirim objek Produk β†’ Detail tampil β†’ tombol Kembali β†’ pop β†’ balik ke Daftar.

20Rangkuman BAB 8

Mindmap & cheatsheet
BAB 8
Navigator = pengelola stack
LIFO
push = buka
pop = kembali
Named Route
pushNamed
Passing Data (constructor)
Return Data (await + pop)

πŸ“‹ Cheatsheet Navigator

// Buka halaman baru Navigator.push(context, MaterialPageRoute( builder: (_) => HalamanBaru())); // Kembali Navigator.pop(context); // Named route Navigator.pushNamed(context, '/detail'); // Kirim data (constructor) HalamanDetail(produk: p); // Terima data balik final r = await Navigator.push(...); Navigator.pop(context, hasil);

21Latihan 1 β€” Push & Pop

Praktik dasar navigasi
🎯 Instruksi Tugas: Buat aplikasi 2 halaman. Halaman A berisi tombol "Lanjut" yang membuka Halaman B menggunakan Navigator.push(). Di Halaman B, sediakan tombol "Kembali" yang memakai Navigator.pop().

Langkah Pengerjaan

1

Buat dua StatelessWidget: HalamanA dan HalamanB.

2

Di Halaman A, tambahkan ElevatedButton dengan Navigator.push menuju Halaman B.

3

Di Halaman B, tambahkan tombol Navigator.pop untuk kembali.

4

Beri AppBar berbeda di tiap halaman agar mudah dibedakan.

πŸ“Š Kriteria Penilaian

KriteriaSkor
Dua halaman terpisah berfungsi25
push() benar membuka Halaman B30
pop() benar kembali ke Halaman A30
Kerapian kode & komentar15
Total100

22Latihan 2 β€” Named Routes & Passing Data

Navigasi tingkat lanjut
🎯 Instruksi Tugas: Buat aplikasi 3 halaman menggunakan Named Routes. Halaman Home menampilkan daftar 3 nama teman. Saat satu nama diklik, kirim nama tersebut ke Halaman Profil dan tampilkan di sana. Tambahkan satu halaman Tentang yang juga didaftarkan di routes.

Langkah Pengerjaan

1

Daftarkan 3 route di routes: {}: '/', '/profil', '/tentang'.

2

Gunakan pushNamed dengan arguments untuk mengirim nama teman ke halaman profil.

3

Ambil data dengan ModalRoute.of(context)!.settings.arguments di Halaman Profil.

4

Tambahkan tombol menuju Halaman Tentang dari Home.

πŸ“Š Kriteria Penilaian

KriteriaSkor
Minimal 3 named route terdaftar25
pushNamed berfungsi semua25
Passing data nama berhasil tampil30
Halaman Tentang dapat diakses10
Kerapian kode10
Total100

23Tugas Akhir BAB 8

Modifikasi Mini Project Katalog Produk
πŸ† Instruksi Tugas Akhir: Kembangkan aplikasi Katalog Produk dari slide 17–19 dengan menambahkan fitur berikut. Tugas dikumpulkan dalam bentuk file .dart + screenshot tiap halaman.

Fitur Wajib Ditambahkan

  • Minimal 5 produk dengan data lengkap (nama, harga, deskripsi, emoji).
  • Halaman Detail menampilkan deskripsi panjang produk.
  • Tombol "Tambah ke Favorit" di Detail yang mengembalikan data (return data) ke Halaman Daftar memakai pop(value).
  • Halaman Daftar menampilkan jumlah favorit yang diterima dari return data.
  • Gunakan minimal 1 Named Route (mis. halaman "Tentang Aplikasi").

πŸ“Š Rubrik Penilaian

AspekBobot
Navigasi push/pop berfungsi20
Passing data produk benar20
Return data favorit berfungsi25
Named route diterapkan15
UI rapi & konsisten10
Kode bersih + komentar10
Total100

Nilai β‰₯ 80 = Sangat Baik Β· 60–79 = Baik Β· < 60 = Perlu remedial.


πŸŽ‰ Selamat! Kamu telah menyelesaikan BAB 8 β€” Navigation & Routing.