Laporan Praktikum 4 - Aplikasi Mobile
Navigasi & Passing Data: Navigator, Konsep Stack, dan Constructor
IF - Universitas Andalas
A. Pendahuluan
Konsep Tumpukan (Stack) di Flutter
Dalam pengembangan aplikasi menggunakan Flutter, terdapat Navigator yang merupakan sebuah widget pengelola rute (halaman). Widget ini bekerja dengan menerapkan konsep tumpukan (stack), yang diibaratkan seperti tumpukan kartu. Pengelolaan halaman dalam konsep tumpukan ini terbagi menjadi dua aksi utama:
- Push: Merupakan proses untuk meletakkan halaman baru di posisi tumpukan yang paling atas.
- Pop: Merupakan proses untuk menghapus atau menutup halaman teratas pada tumpukan agar pengguna dapat kembali ke halaman sebelumnya.
Constructor dan Passing Data
Dalam membuat aplikasi, sering kali dibutuhkan pengiriman data antar halaman. Untuk mengirim data dari Halaman A ke Halaman B, maka Halaman B diwajibkan untuk menyiapkan variabel dan juga Constructor. Berikut adalah komponen utama yang digunakan:
- Variabel Final: Digunakan sebagai tempat penampung data, seperti contohnya variabel title.
- Required: Merupakan sebuah penanda pada Constructor yang menegaskan bahwa data tersebut bersifat wajib diisi saat proses berpindah layar terjadi.
B. Tujuan Praktikum
Adapun tujuan dari pelaksanaan praktikum ini adalah sebagai berikut:
- 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.
C. Alat
Perangkat dan dependensi yang digunakan selama praktikum:
- Flutter SDK
- Code Editor : VS Code atau Android Studio.
- Emulator / Device
D. Langkah-langkah Praktikum
Praktikum diawali dengan menyiapkan beberapa file pada folder lib. Berdasarkan modul, program dibagi menjadi empat file, yaitu main.dart, dashboard_screen.dart, add_transaction_screen.dart, dan transaction_detail_screen.dart. Pembagian ini dilakukan agar setiap bagian aplikasi memiliki fungsi yang jelas dan kode lebih terorganisasi.
a. Membuat File main.dart
File main.dart merupakan file utama yang digunakan untuk menjalankan aplikasi. Pada file ini ditentukan widget utama, tema aplikasi, serta halaman pertama yang ditampilkan.
Baris pertama digunakan untuk mengimpor library Material dari Flutter sehingga komponen seperti MaterialApp, Scaffold, Text, dan widget lainnya dapat digunakan. Baris kedua mengimpor dashboard_screen.dart karena DashboardScreen akan digunakan sebagai halaman awal aplikasi.
Fungsi main() merupakan titik awal eksekusi aplikasi Flutter. Perintah runApp() digunakan untuk menjalankan widget utama aplikasi, yaitu MyApp. Penggunaan const menunjukkan bahwa objek tersebut dapat dibuat sebagai konstanta.
MyApp dibuat sebagai StatelessWidget karena tidak memiliki data yang berubah selama aplikasi berjalan. Method build() digunakan untuk menentukan tampilan dan konfigurasi aplikasi.
MaterialApp digunakan sebagai konfigurasi utama aplikasi Flutter. debugShowCheckedModeBanner: false digunakan untuk menghilangkan tanda debug. Properti title menentukan nama aplikasi, sedangkan theme mengatur warna utama aplikasi menjadi merah. Properti home menentukan DashboardScreen sebagai halaman pertama yang ditampilkan.
b. Membuat Halaman Dashboard
File dashboard_screen.dart digunakan sebagai halaman utama aplikasi. Halaman ini menampilkan saldo, daftar transaksi, tombol untuk menambah transaksi, serta navigasi menuju halaman detail transaksi.
Library Material digunakan untuk menyediakan widget Flutter. File add_transaction_screen.dart digunakan agar dashboard dapat berpindah ke halaman tambah transaksi, sedangkan transaction_detail_screen.dart digunakan untuk membuka halaman detail.
DashboardScreen menggunakan StatelessWidget karena tampilan dashboard pada source code modul tidak memiliki state yang berubah secara langsung. Method build() digunakan untuk membentuk seluruh tampilan dashboard.
Scaffold digunakan sebagai struktur dasar halaman Flutter. AppBar menampilkan judul Dashboard Keuangan dan menggunakan warna merah sebagai warna latar dengan teks berwarna putih.
FloatingActionButton digunakan sebagai tombol untuk menambahkan transaksi. Ketika tombol ditekan, Navigator.push() digunakan untuk berpindah dari dashboard ke AddTransactionScreen. MaterialPageRoute menentukan halaman tujuan yang akan dibuka. Bagian ini merupakan penerapan navigasi push, yaitu menambahkan halaman baru ke dalam stack navigasi.
Bagian body menggunakan SingleChildScrollView agar isi halaman dapat digulir. Column digunakan untuk menyusun komponen secara vertikal. Di dalamnya terdapat sapaan pengguna, kartu saldo, judul transaksi terakhir, dan daftar transaksi.
Fungsi _buildBalanceCard() dibuat untuk memisahkan bagian kartu saldo dari kode utama dashboard. Card digunakan sebagai wadah tampilan, sedangkan Padding memberikan jarak antara isi dan batas kartu. Di dalamnya ditampilkan label Saldo Utama dan nominal saldo sebesar Rp 5.000.000.
Fungsi _buildTransactionList() digunakan untuk menampilkan daftar transaksi. Parameter BuildContext context diperlukan karena bagian ini akan digunakan untuk proses navigasi.
ListTile digunakan untuk menampilkan satu data transaksi secara ringkas. leading menampilkan ikon makanan, title menampilkan nama transaksi, subtitle menampilkan informasi waktu, sedangkan trailing menampilkan nominal transaksi.
Ketika transaksi ditekan, Navigator.push() digunakan untuk membuka TransactionDetailScreen. Pada saat halaman dibuat, data transaksi dikirim melalui constructor berupa title, amount, category, dan date. Dengan demikian, halaman detail dapat menerima data dari halaman dashboard. Mekanisme ini merupakan penerapan passing data melalui constructor.
Transaksi kedua menggunakan mekanisme yang sama, tetapi data yang dikirim disesuaikan dengan transaksi Gaji Bulanan.
c. Membuat Halaman Tambah Transaksi
File add_transaction_screen.dart digunakan untuk membuat formulir pencatatan transaksi. Halaman ini menggunakan StatefulWidget karena terdapat data input yang dapat berubah ketika pengguna mengisi formulir.
AddTransactionScreen menggunakan StatefulWidget karena halaman memiliki input yang nilainya dapat berubah. createState() digunakan untuk membuat objek state yang mengelola kondisi halaman tersebut.
_formKey digunakan untuk mengidentifikasi dan melakukan validasi terhadap Form. Sementara itu, _titleController dan _amountController digunakan untuk mengontrol nilai yang dimasukkan pengguna pada field judul dan nominal.
Padding memberikan jarak antara isi formulir dengan tepi layar. Widget Form digunakan untuk mengelompokkan field input dan melakukan validasi. _formKey dipasang pada properti key agar form dapat diperiksa ketika tombol Simpan ditekan.
TextFormField digunakan untuk menerima judul transaksi. TextEditingController menyimpan nilai yang dimasukkan pengguna. Bagian validator digunakan untuk memastikan field tidak kosong. Jika kosong, pesan “Tidak boleh kosong” akan ditampilkan.
Field nominal memiliki fungsi yang sama dengan field judul, tetapi keyboardType: TextInputType.number digunakan agar keyboard angka ditampilkan ketika pengguna mengisi nominal. Validasi tetap dilakukan untuk memastikan input tidak kosong.
Ketika tombol Simpan ditekan, validate() akan memeriksa seluruh input dalam form. Jika seluruh input valid, aplikasi menampilkan SnackBar sebagai pemberitahuan bahwa transaksi berhasil disimpan. Setelah itu, Navigator.pop(context) digunakan untuk menutup halaman formulir dan kembali ke dashboard. Bagian ini merupakan penerapan navigasi pop.
d. Membuat Halaman Detail Transaksi
File transaction_detail_screen.dart digunakan untuk menampilkan data transaksi secara lebih lengkap. Halaman ini menerima data dari dashboard melalui constructor.
Keempat variabel tersebut digunakan sebagai tempat menyimpan data transaksi yang dikirim dari halaman dashboard. Variabel menggunakan final karena nilainya ditentukan ketika objek halaman dibuat dan tidak diubah selama halaman ditampilkan.
Constructor digunakan untuk menerima data dari halaman sebelumnya. Keyword required menunjukkan bahwa seluruh data tersebut harus diberikan ketika TransactionDetailScreen dibuat. Dengan demikian, halaman detail tidak dapat dibuat tanpa memberikan informasi transaksi yang diperlukan.
Data title dan amount yang diterima melalui constructor ditampilkan menggunakan widget Text. Nilai tersebut akan menyesuaikan transaksi yang dipilih pada halaman dashboard.
Bagian ini digunakan untuk menampilkan kategori, tanggal, dan status transaksi. Nilai category dan date berasal dari data yang dikirim oleh dashboard.
Fungsi _buildDetailRow() digunakan untuk membuat baris informasi dengan format yang sama. Parameter label digunakan untuk nama informasi, sedangkan value digunakan untuk nilainya. Penggunaan fungsi ini membuat kode lebih ringkas dan terstruktur.
Setelah seluruh file dibuat, aplikasi dijalankan melalui emulator atau perangkat Flutter. Berikut adalah tampilan awal menampilkan dashboard dengan saldo dan daftar transaksi
Ketika tombol tambah transaksi ditekan, aplikasi akan berpindah ke halaman Catat Transaksi.
Setelah mengisi judul dan nominal, tombol Simpan ditekan. Aplikasi menampilkan SnackBar sebagai pemberitahuan bahwa transaksi berhasil disimpan, kemudian kembali ke halaman dashboard.
Pada halaman dashboard, ketika pengguna mengklik salah satu transaksi, aplikasi akan membuka halaman Detail Transaksi.
Latihan - Menambahkan Input Tanggal Transaksi Pada Halaman Catat Transaksi
Pada latihan ini dilakukan penambahan satu input baru pada halaman Catat Transaksi untuk mengisi tanggal transaksi. Berdasarkan instruksi modul, input tanggal diletakkan sebelum tombol Simpan. Pengisian tanggal dapat dilakukan menggunakan TextFormField dengan format DD/MM/YYYY, atau menggunakan showDatePicker. Selain itu, input tanggal harus memiliki validasi sehingga tidak boleh dibiarkan kosong.
Pada implementasi ini digunakan TextFormField yang terhubung dengan showDatePicker. Dengan cara tersebut, pengguna dapat memilih tanggal melalui kalender, kemudian tanggal yang dipilih ditampilkan pada field dalam format DD/MM/YYYY
_dateController digunakan untuk mengatur dan menyimpan nilai tanggal yang dipilih oleh pengguna. Nilai tersebut nantinya ditampilkan pada TextFormField tanggal sehingga field dapat menunjukkan tanggal yang telah dipilih.
Fungsi _selectDate() digunakan untuk menampilkan kalender menggunakan showDatePicker. Parameter context digunakan agar date picker dapat ditampilkan pada halaman yang sedang aktif. initialDate menentukan tanggal awal yang ditampilkan dan menggunakan tanggal saat ini. firstDate dan lastDate digunakan untuk menentukan rentang tanggal yang dapat dipilih.
Hasil pemilihan tanggal disimpan dalam variabel picked. Karena pengguna dapat menutup kalender tanpa memilih tanggal, nilai picked dapat bernilai null. Oleh karena itu, dilakukan pengecekan picked != null. Setelah tanggal dipilih, setState() digunakan untuk memperbarui tampilan dan memasukkan tanggal ke dalam _dateController. Nilai tanggal kemudian disusun dalam format DD/MM/YYYY.
Input tanggal ditambahkan pada bagian form sebelum tombol Simpan. TextFormField digunakan untuk menampilkan tanggal yang dipilih. Field ini dihubungkan dengan _dateController agar nilai tanggal dapat ditampilkan setelah pengguna memilih tanggal. Properti readOnly: true digunakan agar pengguna tidak mengetik tanggal secara langsung, melainkan memilihnya melalui kalender. suffixIcon menampilkan ikon kalender sebagai penanda bahwa field tersebut digunakan untuk memilih tanggal.
TextFormField digunakan sebagai tempat untuk menampilkan tanggal transaksi. Field dihubungkan dengan _dateController agar nilai tanggal dapat ditampilkan setelah pengguna memilih tanggal. Properti readOnly: true digunakan agar pengguna tidak mengetik tanggal secara langsung, melainkan memilihnya melalui kalender. suffixIcon menampilkan ikon kalender sebagai penanda bahwa field tersebut digunakan untuk memilih tanggal.
Ketika field ditekan, onTap akan menjalankan fungsi _selectDate(context) sehingga kalender ditampilkan. Pada bagian validator, dilakukan pemeriksaan untuk memastikan field tanggal telah diisi. Apabila masih kosong, sistem akan menampilkan pesan “Tanggal wajib diisi”.
Setelah latihan diterapkan, halaman Catat Transaksi memiliki tiga input utama, yaitu Judul, Nominal, dan Tanggal Transaksi.
Pada bagian tanggal tersedia ikon kalender yang dapat digunakan untuk membuka showDatePicker
Setelah pengguna memilih tanggal, tanggal akan ditampilkan dalam format DD/MM/YYYY.
Jika tanggal belum diisi, aplikasi menampilkan pesan validasi “Tanggal wajib diisi”.
Setelah seluruh input valid, pengguna menekan tombol Simpan dan aplikasi menampilkan SnackBar sebagai pemberitahuan bahwa transaksi berhasil disimpan. Setelah itu, pengguna kembali ke halaman dashboard.
E. Kesimpulan
Berdasarkan praktikum yang telah dilakukan, dapat disimpulkan bahwa pengelolaan perpindahan halaman dan pengiriman data antar layar merupakan komponen esensial dalam pengembangan aplikasi menggunakan antarmuka Flutter. Praktikum ini telah berhasil menerapkan penggunaan widget Navigator yang beroperasi berdasarkan konsep tumpukan (stack). Perintah Navigator.push digunakan untuk membuka atau berpindah ke halaman baru, sedangkan Navigator.pop berfungsi untuk menutup layar aktif dan mengembalikan pengguna ke layar sebelumnya. Selain itu, pengiriman data antar halaman terbukti dapat dilakukan secara efektif dengan menyertakan Constructor pada halaman tujuan, yang memanfaatkan variabel final serta parameter required guna memastikan kelengkapan data saat transisi layar berlangsung.
Secara implementasi, konsep navigasi dan passing data tersebut telah berhasil diintegrasikan ke dalam simulasi aplikasi pencatatan keuangan yang terstruktur ke dalam beberapa file terpisah, meliputi halaman Dashboard, form Tambah Transaksi, dan Detail Transaksi. Sebagai contoh, ketika riwayat transaksi pada Dashboard dipilih, aplikasi mengeksekusi navigasi sekaligus mengirimkan parameter spesifik seperti judul, nominal, kategori, dan tanggal ke halaman detail, sehingga antarmuka dapat menampilkan informasi secara dinamis dan akurat. Lebih lanjut, sistem juga sukses mengombinasikan validasi formulir pencatatan dengan pemunculan notifikasi (SnackBar) yang langsung diikuti oleh eksekusi Navigator.pop. Hal ini memungkinkan formulir tertutup secara otomatis dan mengembalikan pengguna ke halaman utama sesaat setelah proses penyimpanan disimulasikan.