Setelah menyelesaikan praktikum ini, mahasiswa diharapkan mampu:
Navigator.push untuk berpindah ke layar baruNavigator.pop untuk menutup layar setelah aksi selesaiString, int) antar layar melalui ConstructorPada 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.
Navigator.push()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:
title, amount)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
}
}
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.
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.
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.
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.
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.
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.
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.
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.
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 / Method | Fungsi |
|---|---|
| Navigator.push() | Meletakkan halaman baru di tumpukan teratas (berpindah ke layar baru) |
| Navigator.pop() | Menghapus halaman teratas dari tumpukan (kembali ke layar sebelumnya) |
| MaterialPageRoute | Mendefinisikan halaman tujuan beserta transisi animasinya untuk Navigator |
| Constructor + required | Mewajibkan data dikirim saat sebuah widget/halaman dibuat |
| Variabel final | Menampung data yang diterima sebuah StatelessWidget dari constructor-nya |
| onTap (ListTile) | Menjalankan aksi navigasi saat salah satu baris transaksi disentuh |
Input Tanggal Transaksi - ditambahkan satu input baru sebelum tombol Simpan pada add_transaction_screen.dart untuk mengisi Tanggal Transaksi, dikerjakan melalui lima langkah berikut.
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.
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.
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.
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.
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.
Berdasarkan praktikum yang telah dilakukan, dapat disimpulkan bahwa:
Navigator mengelola perpindahan halaman layaknya tumpukan kartu, dengan push untuk maju dan pop untuk kembali.required, sehingga kesalahan lupa mengirim data langsung terdeteksi saat kompilasi, bukan saat aplikasi berjalan.AppBar muncul secara otomatis setiap kali sebuah halaman dibuka lewat Navigator.push, tanpa perlu dibuat manual.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.