Laprak 4 - Navigasi & Passing Data

Praktikum Aplikasi Mobile Pertemuan 4 Zahran Azaria Anvaya - 2411531005

I. Tujuan Praktikum

Setelah menyelesaikan praktikum ini, mahasiswa diharapkan mampu:

  • Menerapkan Navigator.push untuk berpindah ke layar baru
  • Menggunakan Navigator.pop untuk menutup layar setelah aksi selesai
  • Mengirim data (String, int) antar layar melalui Constructor

II. Dasar Teori

Pada aplikasi mobile, perpindahan dari satu layar ke layar lain dikelola oleh Navigator - widget yang bekerja layaknya tumpukan kartu (stack). Setiap kali pengguna membuka halaman baru, halaman tersebut diletakkan di atas tumpukan; setiap kali pengguna kembali, halaman teratas itu dihapus sehingga layar sebelumnya kembali terlihat.

  • Push (Maju) - meletakkan halaman baru di tumpukan teratas, biasanya dipanggil lewat Navigator.push()
  • Pop (Mundur) - menghapus/menutup halaman teratas untuk kembali ke halaman sebelumnya, dipanggil lewat Navigator.pop()

Agar halaman tujuan bisa menampilkan data yang relevan (misalnya detail transaksi yang baru saja diklik), data tersebut perlu dikirim dari Halaman A ke Halaman B melalui Constructor. Halaman B wajib menyiapkan dua hal:

  • Variabel final - tempat penampung data yang dikirim (misal title, amount)
  • required - penanda bahwa data tersebut wajib diisi saat halaman ini dibuka, sehingga Dart akan memberi error di waktu kompilasi jika sampai lupa mengirimnya
dart
class DetailScreen extends StatelessWidget {
  // 1. Siapkan variabel penampung data
  final String title;

  // 2. Buat Constructor yang membutuhkan data ini
  const DetailScreen({
    super.key,
    required this.title // Wajib diisi!
  });

  @override
  Widget build(BuildContext context) {
    return Text(title); // Gunakan data
  }
}

III. Alat dan Bahan

  • Laptop / Komputer
  • Flutter SDK
  • Code Editor: VS Code atau Android Studio
  • Emulator / Device

IV. Langkah - Langkah Praktikum

1 Membuat Halaman Detail Transaksi

Dibuat file baru transaction_detail_screen.dart di dalam folder lib, berisi halaman yang akan menampilkan detail satu transaksi. Dua parameter wajib disiapkan sebagai variabel final - title dan amount - lalu dideklarasikan sebagai required pada constructor, sehingga halaman ini tidak bisa dibuka tanpa mengirimkan kedua data tersebut. Data yang diterima langsung ditampilkan pada UI menggunakan widget Text.

Membuat file transaction_detail_screen.dart
Gambar 1 - Membuat File transaction_detail_screen.dart
Kode Halaman Detail Transaksi
Gambar 2 - Kode Halaman Detail Transaksi dengan Parameter Wajib
2 Pindah ke Detail & Mengirim Data (Push)

Pada dashboard_screen.dart, setiap widget ListTile di daftar transaksi diberi fungsi onTap. Di dalamnya dipanggil Navigator.push() dengan MaterialPageRoute, dan pada bagian builder dibuat instance TransactionDetailScreen yang constructor-nya langsung diisi dengan data baris yang diklik - judul, nominal, kategori, dan tanggal transaksi tersebut.

Navigator.push dengan Passing Data
Gambar 3 - Navigator.push pada onTap ListTile
3 Menutup Layar / Kembali Otomatis (Pop)

Kembali ke file add_transaction_screen.dart dari Modul 3. Setelah validasi berhasil dan SnackBar sukses ditampilkan, ditambahkan satu baris Navigator.pop(context) di akhir blok if, sehingga formulir otomatis tertutup dan aplikasi kembali ke Dashboard tanpa pengguna perlu menekan tombol kembali secara manual.

Navigator.pop setelah Simpan
Gambar 4 - Navigator.pop() Setelah Transaksi Disimpan

V. Source Code Lengkap

Agar modul ini dapat diterapkan dengan baik dan mensimulasikan arsitektur aplikasi nyata, struktur proyek dibagi menjadi empat file terpisah di dalam folder lib.

lib/main.dart - file utama yang menjalankan aplikasi lewat fungsi runApp(), memanggil DashboardScreen sebagai halaman pertama yang dimuat. Tema warna pada ThemeData disesuaikan menjadi merah (Colors.red) untuk Modul 4, berbeda dari tema biru/ungu pada modul sebelumnya. File ini sengaja dibuat seringkas mungkin, karena tugas utamanya hanya menghubungkan konfigurasi aplikasi dengan halaman awal.

Kode Lengkap main.dart
Gambar 5 - Kode Lengkap main.dart

lib/dashboard_screen.dart - halaman utama yang menggabungkan seluruh UI dari Modul 1 & 2 (sapaan, kartu saldo, daftar transaksi) ke dalam satu Scaffold. Bedanya dari modul sebelumnya, tombol-tombol di sini kini benar-benar aktif: FloatingActionButton memanggil Navigator.push menuju AddTransactionScreen, dan setiap onTap pada ListTile membuka TransactionDetailScreen sambil mengirimkan data baris yang diklik. Dengan kata lain, file ini berperan sebagai pusat navigasi yang menghubungkan ketiga halaman lainnya.

Kode Lengkap dashboard_screen.dart
Gambar 6 - Kode Lengkap dashboard_screen.dart

lib/add_transaction_screen.dart - formulir Catat Transaksi yang strukturnya dibawa dari Modul 3, lengkap dengan Form, TextFormField, dan validasi sebelumnya. Perubahan utama di modul ini ada pada bagian onPressed tombol Simpan: setelah validate() lolos dan SnackBar sukses ditampilkan, ditambahkan satu baris Navigator.pop(context) di akhir. Baris ini yang membuat formulir otomatis tertutup dan kembali ke Dashboard tanpa pengguna perlu menekan tombol kembali secara manual.

Kode Lengkap add_transaction_screen.dart
Gambar 7 - Kode Lengkap add_transaction_screen.dart

lib/transaction_detail_screen.dart - halaman baru yang bertugas menampilkan rincian satu transaksi, dibangun sebagai StatelessWidget karena tidak memerlukan state internal. Empat data (title, amount, category, date) diterima lewat constructor dengan parameter required, kemudian disusun rapi menggunakan widget pembantu _buildDetailRow() agar layout baris Kategori, Tanggal, dan Status konsisten. Karena seluruh isinya bergantung pada data kiriman dari Dashboard, halaman ini tidak bisa dibuka sendiri tanpa melalui proses passing data terlebih dahulu.

Kode Lengkap transaction_detail_screen.dart
Gambar 8 - Kode Lengkap transaction_detail_screen.dart

VI. Hasil Akhir: Mockup Halaman Detail

Setelah keempat file di atas diterapkan, daftar transaksi di Dashboard kini dapat diklik dan akan membuka halaman detail berisi data lengkap. Tombol "Panah Kiri" otomatis muncul di AppBar berkat Navigator.push (Flutter menambahkannya secara otomatis setiap kali ada halaman yang bisa di-pop), dan teks judul beserta harga yang tampil menyesuaikan dengan baris transaksi yang diklik sebelumnya.

Mockup Halaman Detail Transaksi
Gambar 9 - Mockup Halaman Detail Transaksi

VII. Hasil & Pembahasan

Praktikum ini berhasil menghubungkan tiga halaman menjadi satu alur navigasi yang utuh: Dashboard, Formulir Catat Transaksi, dan Detail Transaksi. Navigator.push terbukti efektif membawa pengguna ke halaman baru sekaligus membawa data lewat constructor, sementara Navigator.pop mengembalikan pengguna ke halaman sebelumnya baik secara manual (tombol panah kembali bawaan AppBar) maupun otomatis (dipanggil langsung dalam kode setelah transaksi berhasil disimpan).

Penggunaan parameter required pada constructor TransactionDetailScreen juga terbukti berguna sebagai pengaman di waktu kompilasi - Dart akan langsung menandai error jika suatu saat ada pemanggilan halaman detail yang lupa menyertakan salah satu data yang dibutuhkan.

Widget / MethodFungsi
Navigator.push()Meletakkan halaman baru di tumpukan teratas (berpindah ke layar baru)
Navigator.pop()Menghapus halaman teratas dari tumpukan (kembali ke layar sebelumnya)
MaterialPageRouteMendefinisikan halaman tujuan beserta transisi animasinya untuk Navigator
Constructor + requiredMewajibkan data dikirim saat sebuah widget/halaman dibuat
Variabel finalMenampung data yang diterima sebuah StatelessWidget dari constructor-nya
onTap (ListTile)Menjalankan aksi navigasi saat salah satu baris transaksi disentuh

VIII. Latihan / Tugas

Input Tanggal Transaksi - ditambahkan satu input baru sebelum tombol Simpan pada add_transaction_screen.dart untuk mengisi Tanggal Transaksi, dikerjakan melalui lima langkah berikut.

1 Menambahkan Controller Tanggal

Ditambahkan satu TextEditingController baru bernama _dateController, sejajar dengan _titleController dan _amountController yang sudah ada, khusus untuk menampung teks tanggal yang nantinya diisi otomatis lewat date picker.

Kode Controller Tanggal
Gambar 10 - Penambahan Controller Tanggal
2 Membuat Fungsi _selectDate()

Dibuat method _selectDate() bersifat async yang memanggil showDatePicker, dialog kalender bawaan Flutter. Hasil pilihan pengguna diformat menjadi string DD/MM/YYYY menggunakan padLeft(2, '0'), lalu dimasukkan ke _dateController.text di dalam setState() agar UI ikut diperbarui.

Kode Fungsi _selectDate
Gambar 11 - Fungsi _selectDate() dengan showDatePicker
3 Menambahkan Field Tanggal ke UI dan Validasi Wajib Diisi

Ditambahkan satu TextFormField baru sebelum tombol "Simpan", diletakkan setelah kolom Nominal. Properti readOnly: true membuat keyboard tidak muncul saat field disentuh, sehingga pengguna hanya bisa mengisi tanggal lewat date picker yang terbuka ketika ikon pada suffixIcon ditekan. Field tanggal diberi validator agar ikut diperiksa saat _formKey.currentState!.validate() dipanggil. Jika pengguna menekan tombol Simpan tanpa memilih tanggal terlebih dahulu, validator mengembalikan pesan "Tanggal wajib diisi" dan proses simpan otomatis dibatalkan sampai tanggal diisi.

Kode TextFormField Tanggal
Gambar 12 - Field Tanggal Ditambahkan ke UI dan Menambahkan Validasi Wajib Diisi
4 Menyesuaikan dispose() dan Navigasi

Method dispose() diperbarui agar ikut membersihkan _dateController saat halaman ditutup, mencegah memory leak. Alur Navigator.pop(context) dari langkah sebelumnya tetap dipertahankan, sehingga formulir yang sudah menyertakan kolom tanggal ini tetap otomatis kembali ke Dashboard setelah berhasil disimpan.

Kode dispose dengan Date Controller
Gambar 13 - Pembaruan dispose() dan Alur Navigator.pop
✓ Hasil Akhir Latihan

Tampilan formulir setelah kolom Tanggal Transaksi ditambahkan - date picker terbuka saat ikon ditekan, tanggal terpilih otomatis muncul dalam format DD/MM/YYYY, dan pesan error berwarna merah tampil jika kolom masih kosong ketika tombol Simpan ditekan.

Hasil Akhir Latihan Input Tanggal
Hasil Akhir Latihan Input Tanggal
Hasil Akhir Latihan Input Tanggal
Hasil Akhir Latihan Input Tanggal
Gambar 15 - Hasil Akhir Formulir dengan Input Tanggal dan Validasi

IX. Kesimpulan

Berdasarkan praktikum yang telah dilakukan, dapat disimpulkan bahwa:

  1. Navigator mengelola perpindahan halaman layaknya tumpukan kartu, dengan push untuk maju dan pop untuk kembali.
  2. Data dapat dikirim antar halaman dengan aman melalui constructor yang memiliki parameter required, sehingga kesalahan lupa mengirim data langsung terdeteksi saat kompilasi, bukan saat aplikasi berjalan.
  3. Tombol kembali pada AppBar muncul secara otomatis setiap kali sebuah halaman dibuka lewat Navigator.push, tanpa perlu dibuat manual.
  4. Navigator.pop bisa dipanggil langsung dalam kode (bukan hanya lewat tombol UI) untuk menutup halaman secara otomatis setelah sebuah aksi, seperti menyimpan data, berhasil dilakukan.
  5. Memisahkan aplikasi menjadi beberapa file terpisah (main, dashboard, form, detail) membuat struktur proyek lebih rapi dan mendekati arsitektur aplikasi nyata.
Semua langkah berhasil dijalankan dan output sesuai yang diharapkan.
Lihat Repository GitHub