1. Introduction
- Latar Belakang
Flutter menyediakan fitur navigasi untuk mengelola perpindahan antarlayar dalam sebuah aplikasi. Pengelolaan rute atau halaman ini ditangani oleh widget Navigator yang bekerja menyerupai tumpukan kartu. Dalam konsep tumpukan tersebut, mekanisme push digunakan untuk meletakkan halaman baru pada posisi teratas, sedangkan mekanisme pop digunakan untuk menghapus atau menutup halaman teratas agar layar kembali ke halaman sebelumnya. Selain perpindahan layar, aplikasi sering kali membutuhkan pengiriman data antarhalaman, yang dapat dilakukan dengan menyiapkan variabel penampung bersifat final dan mendeklarasikannya melalui pemanggilan constructor yang diatur sebagai parameter wajib. Menerapkan konsep navigasi dan mekanisme pengiriman data ini sangat penting untuk membangun alur interaksi aplikasi lintas layar yang dinamis dan terintegrasi.
Berdasarkan hal tersebut, dilakukan praktik implementasi navigasi dan pengiriman data, meliputi pembuatan antarmuka Detail Transaction Screen, penerapan mekanisme perpindahan layar melalui Push pada Dashboard Screen, penerapan mekanisme penutupan layar otomatis melalui Pop pada Add Transaction Screen, serta penambahan kolom masukan tanggal transaksi beserta fungsi kalender. Kegiatan ini disusun sebagai pemenuhan tugas mata kuliah Aplikasi Mobile pada Departemen Informatika, Universitas Andalas, tahun ajaran 2026/2027.
- Rumusan Masalah
-
Bagaimana penerapan widget StatelessWidget dan constructor dalam membangun kerangka antarmuka Detail Transaction Screen untuk menerima data?
-
Bagaimana penerapan metode Navigator.push dalam melakukan perpindahan layar sekaligus mengirimkan data dari Dashboard Screen?
-
Bagaimana mekanisme metode Navigator.pop dalam menutup layar otomatis dan menampilkan notifikasi pada Add Transaction Screen?
-
Bagaimana cara input tanggal transaksi dikelola dan divalidasi melalui kolom isian serta dialog kalender?
- Tujuan
-
Menerapkan widget StatelessWidget dan constructor dalam membangun kerangka antarmuka Detail Transaction Screen untuk menerima data.
-
Menerapkan metode Navigator.push dalam melakukan perpindahan layar sekaligus mengirimkan data dari Dashboard Screen.
-
Menerapkan metode Navigator.pop dalam menutup layar otomatis dan menampilkan notifikasi pada Add Transaction Screen.
-
Menerapkan input tanggal transaksi melalui kolom isian serta dialog kalender yang dilengkapi dengan validasi.
2. Methodology
- Detail Transaction Screen
-
Kelas DetailTransactionScreen merupakan StatelessWidget, sehingga antarmuka yang dibangun bersifat statis dan tidak berubah setelah dirender.
-
Pada kelas tersebut, dideklarasikan variabel bertipe String bernama title dan amount untuk menampung data yang akan ditampilkan.
-
Nilai untuk kedua variabel tersebut wajib diserahkan dari layar sebelumnya melalui pemanggilan constructor, yang didefinisikan menggunakan penanda required.
-
Pada metode build, dikembalikan widget Scaffold yang menyediakan kerangka visual dasar sebuah halaman, terdiri atas bagian appBar dan body.
-
Bagian appBar diisi dengan widget AppBar, yang menampilkan bilah judul berisi tulisan "Detail Transaksi" melalui properti title.
-
Bagian body diisi dengan widget Center, yang memosisikan child-nya tepat di tengah area layar yang tersedia.
-
Di dalam Center terdapat widget Column yang menyusun elemen-elemen pada properti children secara vertikal dari atas ke bawah sesuai urutan penulisannya.
-
Elemen pertama berupa widget Text yang menampilkan isi dari variabel title, dan diberi gaya tulisan melalui properti style menggunakan TextStyle dengan ukuran huruf 24 pada properti fontSize.
-
Elemen kedua berupa widget Text yang menampilkan isi dari variabel amount, dan diberi gaya tulisan melalui properti style menggunakan TextStyle dengan ukuran huruf 20 pada properti fontSize.

- Pindah ke Detail dan Mengirim Data (Push)
-
Pada antarmuka daftar transaksi, digunakan widget ListTile untuk menyusun dan menampilkan sebuah baris data.
-
Properti leading pada ListTile diisi dengan widget Icon yang menampilkan simbol Icons.fastfood pada bagian kiri baris.
-
Properti title diisi dengan widget Text yang menampilkan tulisan "Makan Siang" sebagai nama transaksi.
-
Properti trailing diisi dengan widget Text yang menampilkan tulisan "- Rp 50.000" pada bagian kanan baris.
-
Untuk menangani interaksi pengguna, dideklarasikan fungsi onTap yang akan dieksekusi ketika baris ListTile tersebut ditekan.
-
Di dalam fungsi onTap, dipanggil metode Navigator.push untuk melakukan perpindahan halaman ke layar baru dengan menumpuknya di atas riwayat navigasi saat ini.
-
Metode Navigator.push menerima argumen context serta objek MaterialPageRoute untuk mendefinisikan rute halaman baru dengan animasi transisi standar bergaya material design.
-
Pada objek MaterialPageRoute, properti builder diisi dengan fungsi anonim yang mengembalikan pemanggilan kelas DetailTransactionScreen sebagai halaman tujuan.
-
Saat kelas DetailTransactionScreen dipanggil, data dikirimkan menuju halaman tersebut melalui constructor dengan mengisi parameter title dengan nilai "Makan Siang" dan parameter amount dengan nilai "- Rp 50.000".

- Menutup Layar dan Kembali Otomatis
-
Pada antarmuka formulir, digunakan widget ElevatedButton untuk memicu aksi penyimpanan, yang menampilkan tulisan "Simpan Transaksi" melalui widget Text pada properti child.
-
Properti onPressed pada ElevatedButton diisi dengan fungsi anonim yang akan dieksekusi saat tombol tersebut ditekan oleh pengguna.
-
Di dalam fungsi onPressed, dilakukan pemeriksaan keabsahan masukan formulir dengan memanggil metode validate pada _formKey.currentState!.
-
Apabila seluruh masukan dinyatakan sah, aplikasi akan memunculkan pesan notifikasi dari bagian bawah layar menggunakan pemanggilan metode showSnackBar pada ScaffoldMessenger.of(context).
-
Metode showSnackBar tersebut menerima argumen berupa instansiasi widget SnackBar, yang menampilkan tulisan "Menyimpan Transaksi..." melalui widget Text pada properti content.
-
Setelah pesan notifikasi ditampilkan, dipanggil metode pop pada kelas Navigator dengan meneruskan argumen context untuk menutup layar formulir secara otomatis dan menghapusnya dari riwayat navigasi, sehingga pengguna langsung dikembalikan ke layar sebelumnya.

- Main File dan Root Widget
-
Pada fungsi main, aplikasi dijalankan melalui pemanggilan runApp dengan argumen berupa instansiasi kelas MyApp, sehingga proses pembangunan antarmuka dimulai dari widget tersebut.
-
Kelas MyApp merupakan StatelessWidget, sehingga tampilan dasar aplikasi yang dibangun bersifat statis dan tidak mengalami perubahan state secara internal.
-
Pada metode build milik kelas MyApp, dikembalikan widget MaterialApp sebagai root widget aplikasi, yang menyediakan struktur dan konfigurasi dasar bergaya material design.
-
Properti debugShowCheckedModeBanner pada MaterialApp diatur bernilai false agar pita penanda mode debug di sudut kanan atas layar disembunyikan.
-
Properti title diisi dengan tulisan "Expense Tracker - Modul 4" yang berfungsi sebagai judul deskriptif aplikasi.
-
Properti theme diisi dengan instansiasi kelas ThemeData untuk mengatur tema visual, dengan properti primarySwatch diatur ke warna merah melalui Colors.red sebagai warna utama aplikasi.
-
Properti home pada MaterialApp dihubungkan dengan widget DashboardScreen, sehingga kelas tersebut akan dijadikan sebagai layar halaman utama yang pertama kali ditampilkan ketika aplikasi dimuat.

- Dashboard Screen
-
Pada kelas DashboardScreen yang merupakan StatelessWidget, dikembalikan widget Scaffold pada metode build sebagai kerangka visual dasar halaman utama.
-
Bagian appBar diisi dengan widget AppBar yang menampilkan bilah judul berisi tulisan "Dashboard Keuangan" melalui properti title, warna latar merah melalui backgroundColor dengan Colors.red, dan warna tulisan putih melalui foregroundColor dengan Colors.white.
-
Properti floatingActionButton pada Scaffold diisi widget FloatingActionButton dengan warna merah dan tulisan putih, yang menampilkan simbol Icons.add melalui properti child untuk tombol tambah transaksi.
-
Properti onPressed pada FloatingActionButton memanggil metode Navigator.push dengan objek MaterialPageRoute untuk memindahkan layar ke kelas AddTransactionScreen saat tombol tersebut ditekan.
-
all.
-
Di dalam SingleChildScrollView, properti child diisi widget Column yang menyusun elemen-elemen secara vertikal dengan rata kiri melalui properti crossAxisAlignment yang diatur ke CrossAxisAlignment.start.
-
Elemen pertama pada Column berupa widget Text yang menampilkan sapaan "Halo Budi" dengan ukuran huruf 20 dan bergaya tebal melalui properti fontWeight.bold pada TextStyle, dilanjutkan dengan widget SizedBox setinggi 20 piksel sebagai jarak.
-
Elemen ketiga memanggil metode _buildBalanceCard yang mengembalikan widget Card untuk menampilkan informasi saldo pengguna.
-
Pada metode _buildBalanceCard, widget Card diberi efek bayangan melalui properti elevation bernilai 4, warna merah aksen melalui Colors.redAccent, dan bingkai membulat melalui properti shape dengan RoundedRectangleBorder berukuran 16 melalui BorderRadius.circular.
-
Di dalam Card tersebut terdapat widget Padding sebesar 20 piksel yang membungkus widget Column, berisi tulisan "Saldo utama" berukuran 16 dengan warna putih transparan melalui Colors.white70, disusul SizedBox setinggi 8 piksel, dan diakhiri tulisan "Rp 5.000.000" berukuran huruf 28, tebal, berwarna putih solid.
-
Kembali pada susunan body utama, elemen setelah kartu saldo adalah SizedBox setinggi 20 piksel dan widget Text bertuliskan "Transaksi Akhir" dengan ukuran huruf 18 bergaya tebal, lalu diikuti SizedBox setinggi 12 piksel.
-
Elemen terakhir pada body memanggil metode _buildTransactionList dengan meneruskan argumen context.
-
Pada metode _buildTransactionList, dikembalikan widget Card dengan elevation bernilai 2 yang memuat widget Column berisi daftar riwayat transaksi.
-
Elemen pertama pada daftar transaksi tersebut berupa widget ListTile yang menampilkan data pengeluaran, di mana properti leading diisi CircleAvatar berwarna oranye berisi widget Icon dengan simbol Icons.fastfood berwarna putih.
-
Properti title pada ListTile tersebut diisi widget Text "Makan Siang", properti subtitle diisi tulisan "Hari ini", dan properti trailing diisi tulisan "- Rp 50.000" berwarna merah dan tebal.
-
push untuk berpindah ke halaman TransactionDetailScreen, sekaligus mengirimkan data berupa argumen title "Makan siang", amount "- Rp 50.000", category "Makanan", dan date "13 September 2026".
-
Elemen berikutnya di dalam Column berupa widget Divider setinggi 1 piksel yang bertugas sebagai garis pemisah antarbaris transaksi.
-
Elemen terakhir berupa widget ListTile untuk data pemasukan, di mana properti leading diisi CircleAvatar berwarna hijau yang membungkus ikon Icons.attach_money berwarna putih.
-
Properti title pada ListTile kedua menampilkan teks "Gaji Bulanan", properti subtitle menampilkan "1 September 2026", dan properti trailing menampilkan teks "+ Rp 5.000.000" berwarna hijau tebal melalui Colors.green pada TextStyle.
-
Properti onTap pada ListTile kedua juga memanggil Navigator.push menuju TransactionDetailScreen dengan mengirimkan data yang sesuai dengan transaksi pemasukan tersebut.

- Add Transaction Screen
-
Kelas AddTransactionScreen merupakan StatefulWidget yang membentuk objek state bernama _AddTransactionScreenState melalui metode createState, sehingga tampilan antarmuka dapat diperbarui secara dinamis saat terjadi interaksi pengguna.
-
Pada kelas _AddTransactionScreenState, dideklarasikan variabel _formKey menggunakan GlobalKey untuk mengelola dan memvalidasi state dari formulir secara keseluruhan.
-
Dideklarasikan pula tiga buah TextEditingController bernama _titleController, _amountController untuk menampung data masukan pengguna, serta variabel _selectedDate bertipe DateTime.
-
Metode dispose dipanggil untuk membersihkan _titleController, dan _amountController dari memori sesaat sebelum halaman ditutup guna mencegah kebocoran memori.
-
Pada metode build, dikembalikan widget Scaffold sebagai kerangka visual dasar halaman, dengan bagian appBar diisi widget AppBar bertuliskan "Catat Transaksi" melalui properti title, berlatar merah, dan teks berwarna putih.
-
Bagian body diisi widget Padding yang memberikan jarak ruang sebesar 16 piksel di semua sisi, yang di dalamnya membungkus widget Form.
-
Properti key pada widget Form dihubungkan dengan variabel _formKey agar seluruh masukan di dalamnya dapat divalidasi secara bersamaan.
-
Di dalam Form, digunakan widget Column yang menyusun elemen-elemen formulir secara vertikal dan ditarik memenuhi lebar layar melalui properti crossAxisAlignment yang diatur ke CrossAxisAlignment.stretch.
-
Elemen pertama berupa widget TextFormField yang dihubungkan ke _titleController untuk masukan judul, diberi dekorasi berupa InputDecoration dengan labelText "Judul" dan bingkai OutlineInputBorder, serta memiliki properti validator yang akan mengembalikan pesan kesalahan "Tidak Boleh Kosong" apabila kolom isian tidak diisi.
-
Setelah diselingi widget SizedBox setinggi 16 piksel, elemen ketiga berupa TextFormField untuk masukan nominal yang dihubungkan ke _amountController, diatur agar memunculkan papan ketik angka melalui keyboardType dengan TextInputType.number, berlabel "Nominal", dan juga memvalidasi kekosongan masukan.
-
Setelah diselingi SizedBox setinggi 32 piksel, elemen terakhir berupa widget ElevatedButton yang menampilkan tulisan "Simpan" berukuran huruf 16 melalui widget Text.
-
Tombol tersebut diberi gaya tampilan melalui ElevatedButton.styleFrom dengan warna latar merah, teks putih, dan jarak pengisi vertikal 16 piksel melalui EdgeInsets.symmetric.
-
Fungsi onPressed pada ElevatedButton akan memanggil _formKey.currentState!.validate() untuk memeriksa keabsahan seluruh kolom isian; bila bernilai benar, aplikasi akan memunculkan pesan "Transaksi Berhasil Disimpan" berlatar hijau melalui widget SnackBar menggunakan ScaffoldMessenger.of(context).showSnackBar, lalu memanggil Navigator.pop(context) untuk menutup halaman formulir.

- Transaction Detail Screen
-
Pada kelas TransactionDetailScreen yang merupakan StatelessWidget, dideklarasikan variabel bertipe String bernama title, amount, category, dan date untuk menampung data yang akan ditampilkan.
-
Nilai untuk keempat variabel tersebut wajib diserahkan saat kelas diinstansiasi melalui pemanggilan constructor, yang didefinisikan menggunakan penanda required.
-
Pada metode build, dikembalikan widget Scaffold yang menyediakan kerangka visual dasar halaman, terdiri atas bagian appBar dan body.
-
Bagian appBar diisi dengan widget AppBar, yang menampilkan bilah judul berisi tulisan "Detail Transaksi" melalui properti title, warna latar merah melalui backgroundColor dengan Colors.red, serta warna tulisan putih melalui foregroundColor dengan Colors.white.
-
Bagian body diisi widget Padding yang memberikan jarak ruang kosong sebesar 24 piksel di semua sisi melalui properti padding menggunakan EdgeInsets.all.
-
Di dalam Padding, properti child diisi widget Column yang menyusun elemen-elemen secara vertikal, dengan properti crossAxisAlignment diatur ke CrossAxisAlignment.center agar seluruh elemen diposisikan di tengah layar secara horizontal.
-
Elemen pertama pada properti children di dalam Column berupa widget Icon yang menampilkan simbol Icons.receipt_long berukuran 80 dengan warna merah aksen melalui Colors.redAccent.
-
Elemen kedua berupa widget SizedBox setinggi 24 piksel yang berfungsi memberikan jarak kosong vertikal antarelemen.
-
Elemen ketiga berupa widget Text yang menampilkan isi dari variabel title, diberi gaya tulisan tebal dan ukuran huruf 24 melalui properti fontWeight.bold serta fontSize pada TextStyle.
-
Elemen keempat berupa widget SizedBox setinggi 8 piksel sebagai jarak tambahan.
-
Elemen kelima berupa widget Text yang menampilkan isi dari variabel amount, diberi gaya tulisan tebal, ukuran huruf 32, dan warna merah melalui properti color dengan Colors.red pada TextStyle.
-
Elemen keenam berupa widget Divider yang menampilkan garis pemisah horizontal setebal 2 piksel melalui properti thickness dengan tinggi area 40 piksel melalui properti height.
-
Elemen ketujuh memanggil metode _buildDetailRow dengan mengirimkan argumen berupa teks "Kategori" dan isi variabel category, dilanjutkan elemen kedelapan berupa SizedBox setinggi 16 piksel.
-
Elemen kesembilan kembali memanggil metode _buildDetailRow dengan mengirimkan argumen berupa teks "Tanggal" dan isi variabel date, dilanjutkan elemen kesepuluh berupa SizedBox setinggi 16 piksel.
-
Elemen kesebelas memanggil metode _buildDetailRow dengan mengirimkan argumen berupa teks "Status" dan teks "Berhasil".
-
Pada metode _buildDetailRow yang menerima parameter bertipe String bernama label dan value, dikembalikan widget Row yang menyusun elemen-elemen secara horizontal.
-
Properti mainAxisAlignment pada Row diatur ke MainAxisAlignment.spaceBetween agar elemen-elemen di dalamnya didorong menyebar ke ujung kiri dan kanan batas layar.
-
Widget Row tersebut memuat dua widget Text; Text pertama menampilkan data dari parameter label dengan ukuran huruf 16 dan warna abu-abu melalui Colors.grey pada TextStyle, sedangkan Text kedua menampilkan data dari parameter value dengan ukuran huruf 16 dan bergaya tebal melalui fontWeight.bold.

- Pengerjaan Tugas Praktikum
-
Pada kelas _AddTransactionScreenState, dideklarasikan TextEditingController bernama _dateController untuk menampung teks masukan tanggal, serta variabel _selectedDate bertipe DateTime untuk menyimpan objek tanggal yang dipilih pengguna.
-
Dideklarasikan fungsi asinkron _pilihTanggal yang memanggil showDatePicker untuk menampilkan dialog kalender, dengan argumen context, initialDate berisi _selectedDate atau DateTime.now(), firstDate berisi tahun 2000 melalui DateTime(2000), dan lastDate berisi tahun 2100 melalui DateTime(2100).
-
Di dalam fungsi _pilihTanggal, apabila tanggal dipilih dan nilainya tidak null, data tersebut disimpan ke variabel _selectedDate, lalu komponen hari dan bulan diformat menjadi dua digit menggunakan padLeft(2, '0') sebelum digabungkan dengan tahun menjadi format DD/MM/YYYY dan dimasukkan ke _dateController.text.
-
Pada metode dispose, ditambahkan pemanggilan _dateController.dispose() untuk membersihkan memori controller saat halaman ditutup.
-
Pada metode build, ditambahkan sebuah widget TextFormField sebelum tombol simpan yang properti controller-nya dihubungkan ke _dateController.
-
Widget tersebut memunculkan papan ketik angka melalui properti keyboardType dengan nilai TextInputType.number, dan diberi dekorasi melalui InputDecoration dengan labelText "Tanggal Transaksi" serta bingkai OutlineInputBorder.
-
Pada InputDecoration tersebut, ditambahkan ikon kalender di awal melalui properti prefixIcon dengan widget Icon bersimbol Icons.calendar_today.
-
Ditambahkan pula ikon interaktif di akhir baris isian melalui properti suffixIcon yang diisi widget IconButton dengan simbol Icons.add pada properti icon, di mana properti onPressed diatur untuk memanggil fungsi _pilihTanggal saat ditekan.
-
Properti validator pada TextFormField diatur untuk mengembalikan pesan "Tanggal wajib diisi" apabila nilai masukan kosong, "Format tanggal harus DD/MM/YYYY" apabila pola karakter tidak sesuai dengan batasan RegExp, dan null apabila masukan dinyatakan sah.

3. Results & Discussion
- Analisis Hasil Praktikum dan Tugas Praktikum
Tampilan antarmuka DashboardScreen bertindak sebagai halaman utama yang memuat sebuah AppBar berwarna merah dengan judul "Dashboard Keuangan" berwarna putih. Pada bagian isi, terdapat teks sapaan pengguna yang diikuti oleh sebuah kartu informasi bersudut membulat dengan warna latar merah aksen, yang merangkum informasi "Saldo utama" sebesar "Rp 5.000.000". Di bawah kartu saldo, layar menampilkan daftar "Transaksi Akhir" yang disusun menggunakan widget Card berisi barisan ListTile. Setiap baris mewakili satu riwayat transaksi, menampilkan ikon kategori di sebelah kiri, nama transaksi beserta keterangan waktu di tengah, serta nominal pemasukan atau pengeluaran pada bagian kanan yang secara otomatis diberi warna hijau atau merah sesuai jenisnya. Pengguna dapat berinteraksi dengan menekan baris daftar tersebut untuk membuka antarmuka TransactionDetailScreen, yang menyajikan rincian lengkap transaksi yang disusun terpusat dari atas ke bawah, meliputi ikon tanda terima, judul transaksi, nominal berukuran besar, sebuah garis pemisah, dan baris rincian penyerta lainnya di bagian bawah.
Untuk mencatat aktivitas keuangan baru, pengguna dapat menekan tombol FloatingActionButton berlambang tambah di sudut kanan bawah halaman utama, yang akan mengarahkan layar ke antarmuka AddTransactionScreen. Halaman ini memiliki AppBar bertuliskan "Catat Transaksi" dan memuat sebuah formulir berisi kolom-kolom isian yang ditarik memenuhi lebar layar. Formulir praktikum ini mencakup kolom masukan "Judul" untuk nama aktivitas, serta kolom "Nominal" yang diatur agar memunculkan papan ketik angka saat diklik. Pada bagian paling bawah dari susunan formulir, terdapat tombol "Simpan" berwarna merah yang berfungsi sebagai pemicu utama aksi pengiriman data.
Validasi pada formulir diterapkan untuk memastikan keutuhan data sebelum sistem melakukan pemrosesan penyajian lebih lanjut. Kolom masukan "Judul" dan "Nominal" divalidasi secara khusus melalui pemeriksaan kekosongan nilai. Evaluasi keabsahan ini baru dijalankan secara serentak terhadap seluruh kolom ketika pengguna menekan tombol "Simpan", melalui pemanggilan fungsi validasi pada state formulir secara global. Apabila terdapat kolom yang dibiarkan kosong oleh pengguna, pesan kesalahan berbunyi "Tidak Boleh Kosong" untuk judul dan "Tidak boleh Kosong" untuk nominal akan dimunculkan dengan teks berwarna merah tepat di bawah garis batas kolom yang bermasalah. Pesan ini muncul seketika tanpa menghapus atau mengubah data yang mungkin sudah terisi dengan benar di kolom lain. Sebaliknya, apabila seluruh syarat masukan pada formulir telah terpenuhi dan dinyatakan sah, halaman formulir akan langsung ditutup secara otomatis untuk mengembalikan pandangan ke halaman utama, disusul dengan kemunculan pesan notifikasi keberhasilan melalui SnackBar berlatar hijau dengan tulisan "Transaksi Berhasil Disimpan" di bagian bawah layar.



- Hasil Analisis Tugas Praktikum
Sebagai pemenuhan tugas praktikum, antarmuka AddTransactionScreen dimodifikasi dengan menyisipkan sebuah kolom masukan baru yang dikhususkan untuk mencatat waktu terjadinya transaksi. Kolom berlabel "Tanggal Transaksi" tersebut diposisikan secara vertikal sesudah kolom nominal dan tepat sebelum tombol "Simpan", menggunakan widget TextFormField. Secara visual, kolom isian ini didesain lebih informatif dengan menyematkan ikon kalender pada sisi kiri batas isian, serta sebuah ikon tambah interaktif pada sisi kanan batas isian. Ikon tambah tersebut difungsikan sebagai pemicu pemanggilan metode showDatePicker, yang memunculkan dialog kalender ke atas layar agar pengguna dapat memilih tanggal secara presisi tanpa harus mengetik manual, yang kemudian nilainya diteruskan secara otomatis ke dalam kolom isian.
Penerapan kolom tanggal ini juga diiringi dengan mekanisme validasi data yang diintegrasikan ke dalam state formulir secara global untuk menjaga konsistensi data masukan. Evaluasi keabsahan data dijalankan secara serentak bersama kolom lainnya tepat ketika pengguna menekan tombol "Simpan". Apabila pengguna mencoba menyimpan formulir tanpa mengisi tanggal sama sekali, fungsi validator pada TextFormField tersebut akan langsung mencegat eksekusi penutupan layar dan menampilkan pesan kesalahan bertuliskan "Tanggal wajib diisi" dengan warna tulisan merah tepat di bagian bawah kolom. Lebih lanjut, dari struktur kode yang telah dibuat, kolom ini juga dibekali evaluasi ekspresi reguler berjenjang yang memastikan masukan harus mematuhi format baku DD/MM/YYYY. Proses validasi yang ketat ini bertujuan mencegah aplikasi dari galat pemrosesan data dan memastikan setiap riwayat transaksi memiliki keterangan waktu yang terstandardisasi dan sah.

4. Conclusion
Berdasarkan praktik yang telah dilakukan, dapat disimpulkan bahwa perpindahan antarlayar pada aplikasi Flutter dapat dikelola secara efisien menggunakan kelas Navigator melalui metode push untuk membuka halaman baru dan pop untuk menutup halaman aktif. Pengiriman data antarhalaman dilakukan secara langsung dengan mendefinisikan variabel final yang wajib diisi melalui pemanggilan constructor pada kelas tujuan, sedangkan antarmuka detail transaksi disusun secara terpusat menggunakan StatelessWidget dan Scaffold. Mekanisme penanganan formulir yang memanfaatkan StatefulWidget, TextFormField, dan GlobalKey memungkinkan aplikasi memvalidasi masukan pengguna secara serentak, termasuk pemanggilan dialog kalender secara asinkron untuk akurasi data waktu. Dengan demikian, penerapan sistem navigasi berbasis tumpukan, metode pengiriman data antarkelas, serta manajemen keabsahan formulir menjadi dasar penting dalam pengembangan alur interaksi aplikasi menggunakan Flutter