Laporan Praktikum 1 (Input Widgets dan Basic Form)

Laporan Praktikum 1 (Input Widgets dan Basic Form)

Sep 14, 2026 •Daffa Aira Adrin

1. Introduction

A. Latar Belakang

Aplikasi mobile pada umumnya tidak hanya menampilkan informasi kepada pengguna, tetapi juga menerima masukan berupa data yang dikirimkan melalui papan ketik. Pada Flutter, kebutuhan tersebut dipenuhi oleh sekelompok widget masukan yang dikenal sebagai basic form, meliputi TextField, TextFormField, CheckBox, Switch, Dropdown, Radio, dan sejenisnya. Widget TextField berfungsi menerima masukan teks serta mengelola isinya melalui TextEditingController, sedangkan TextFormField merupakan versi lengkapnya yang telah terintegrasi dengan logika validasi dan manajemen state sebuah form. Pengelolaan masukan tersebut ditunjang oleh GlobalKey<FormState> yang memungkinkan FormState diakses dari luar widget, method validate yang menjalankan seluruh fungsi validator pada setiap kolom masukan, serta method setState yang memberitahukan kepada Flutter bahwa state pada StatefulWidget telah berubah dan antarmuka perlu dibangun ulang.


Berdasarkan hal tersebut, dilakukan praktik implementasi basic form pada Flutter, meliputi pembuatan tampilan masukan menggunakan widget TextField beserta pengelolaan nilainya melalui TextEditingController,  serta penerapan widget TextFormField di dalam Form dengan validasi melalui properti validator dan penampilan hasil melalui SnackBar. Kegiatan ini disusun sebagai pemenuhan tugas praktikum mata kuliah Aplikasi Mobile pada Departemen Informatika, Universitas Andalas, tahun ajaran 2026/2027.

B. Rumusan Masalah

  1. Bagaimana penerapan widget TextField dalam membuat tampilan basic form untuk menerima masukan teks dari pengguna?
  2. Bagaimana pengelolaan nilai masukan menggunakan TextEditingController beserta pelepasan sumber dayanya melalui method dispose?
  3. Bagaimana penerapan widget TextFormField beserta properti validator dalam memeriksa kesesuaian masukan dengan aturan yang ditetapkan?
  4. Bagaimana pemanfaatan GlobalKey<FormState> dan method validate dalam mengendalikan validasi seluruh kolom masukan serta menampilkan hasilnya kepada pengguna?

C. Tujuan

  1. Memahami penerapan widget TextField dalam membuat tampilan basic form untuk menerima masukan teks dari pengguna.
  2. Memahami pengelolaan nilai masukan menggunakan TextEditingController beserta pelepasan sumber dayanya melalui method dispose.
  3. Memahami penerapan widget TextFormField beserta properti validator dalam memeriksa kesesuaian masukan dengan aturan yang ditetapkan.
  4. Memahami pemanfaatan GlobalKey<FormState> dan method validate dalam mengendalikan validasi seluruh kolom masukan serta menampilkan hasilnya kepada pengguna.


2. Methodology

A. Basic Form TextField

  1. Buat berkas dart baru dengan nama form-textfield di dalam folder lib, impor pustaka package:flutter/material.dart, lalu pada fungsi main aplikasi dijalankan melalui pemanggilan runApp dengan argumen berupa instansiasi kelas MyApp.
  2. Pada method build kelas MyApp, dikembalikan widget MaterialApp sebagai root widget aplikasi, dengan properti home berisi Scaffold yang menyediakan kerangka visual dasar sebuah halaman, terdiri atas bagian appBar dan body.
  3. Bagian appBar diisi widget AppBar yang menampilkan bilah judul bertuliskan "Basic Form" melalui properti title, sedangkan bagian body diisi widget kustom MyForm yang diturunkan dari StatefulWidget dan mengembalikan objek _MyFormState melalui method createState.
  4. Pada method build kelas _MyFormState, dikembalikan widget Padding sebesar 20 piksel melalui EdgeInsets.all, membungkus widget Column yang menyusun elemen-elemen pada properti children secara vertikal dan dirapatkan ke sisi kiri melalui crossAxisAlignment.
  5. Elemen pertama berupa widget Text bertuliskan "Masukkan nama anda :" sebagai keterangan bagi pengguna, dipisahkan oleh widget SizedBox setinggi 10 piksel dari elemen berikutnya.
  6. Elemen kedua berupa widget TextField yang menerima masukan teks dari papan ketik, dengan tampilannya diatur melalui properti decoration berisi InputDecoration, meliputi label "Nama Lengkap" pada labelText, teks bayangan "Misalnya masnoer" pada hintText, bingkai kotak melalui OutlineInputBorder, serta simbol Icons.person pada prefixIcon.
  7. Setelah SizedBox setinggi 20 piksel, elemen terakhir berupa widget ElevatedButton berlabel "Tampilkan mama" yang memakai ElevatedButton.styleFrom untuk mengatur warna latar kuning dan warna teks hitam, sedangkan fungsi onPressed masih dibiarkan kosong sehingga tombol belum menjalankan perintah apa pun.


B. Penambahan Controller

  1. Di dalam kelas _MyFormState, dideklarasikan variabel _textEditingController bertipe TextEditingController yang berfungsi menyimpan serta mengelola nilai teks pada widget TextField, sehingga isi kolom masukan dapat dibaca dari kode.
  2. Method dispose ditimpa melalui anotasi @override untuk memanggil _textEditingController.dispose, lalu diteruskan dengan super.dispose, sehingga controller tersebut dilepaskan dari memori ketika widget dihapus dari pohon widget dan kebocoran memori dapat dihindari.

C. Penambahan Controller pada TextField

  1. Pada widget TextField, ditambahkan properti controller yang diisi dengan _textEditingController, properti keyboardType bernilai TextInputType.text untuk menampilkan papan ketik jenis teks, serta properti onChanged berupa fungsi callback yang mencetak teks terkini ke konsol setiap kali isi kolom masukan berubah.
  2. Kata kunci const pada widget TextField dihapus karena _textEditingController bukan nilai konstanta pada saat kompilasi, sedangkan const pada InputDecoration tetap dipertahankan sehingga dekorasi kolom masukan hanya dibangun satu kali.


D. Penambahan Controller pada ElevatedButton

  1. Fungsi onPressed pada widget ElevatedButton diisi dengan blok perintah yang mengambil isi kolom masukan melalui properti text pada _textEditingController, lalu menyimpannya ke dalam variabel inputText..
  2. Nilai tersebut ditampilkan melalui ScaffoldMessenger.of(context).showSnackBar yang memunculkan widget SnackBar pada bagian bawah layar, dengan properti content berisi widget Text bertuliskan nama yang dimasukkan pengguna.
  3. Output pada web:


E.Basic Form TextFormField

  1. Dibuat file .dart baru pada folder \lib dengan nama form-textformfield.dart
  2. Pada method build kelas MyApp, dikembalikan widget MaterialApp sebagai root widget aplikasi, dengan properti home berisi Scaffold yang bagian appBar-nya menampilkan bilah judul bertuliskan "Basic Form TextFormField" dan bagian body-nya diisi widget kustom MyFormText
  3. Kelas MyFormText diturunkan dari StatefulWidget dan mengembalikan objek _MyFormTextState melalui method createState, karena isi formulir dapat berubah selama aplikasi berjalan.
  4. Pada method build kelas _MyFormTextState, dikembalikan widget Column yang menyusun seluruh elemen formulir pada properti children secara vertikal dari atas ke bawah, dengan widget SizedBox setinggi 10 piksel sebagai jarak antarelemen.
  5. Elemen masukan berupa dua widget TextFormField, yaitu versi lengkap dari TextField yang dapat terhubung dengan logika validasi sebuah form, dengan tampilan masing-masing diatur melalui properti decoration berisi InputDecoration berlabel "Nama : " dan "Email : " serta bingkai kotak melalui OutlineInputBorder.
  6. Elemen terakhir berupa widget SizedBox dengan properti width bernilai double.infinity yang membungkus widget ElevatedButton berlabel "Submit", sehingga lebar tombol memenuhi seluruh lebar layar, sedangkan fungsi onPressed masih dibiarkan kosong karena validasi belum ditambahkan.
  7. Output pada web:


F. Penambahan Controller pada Class _MyFormTextState

  1. Di dalam kelas _MyFormTextState, dideklarasikan variabel _formKey bertipe GlobalKey<FormState> sebagai kunci unik untuk mengakses FormState dari luar widget Form, serta dua buah TextEditingController, yaitu _nameController dan _emailController, yang mengelola nilai masukan pada masing-masing TextFormField.
  2. Method dispose ditimpa melalui anotasi @override untuk melepaskan kedua controller tersebut melalui pemanggilan dispose miliknya, lalu diteruskan dengan super.dispose agar tidak terjadi kebocoran memori ketika widget dihapus dari pohon widget.
  3. Method _submitForm dibuat untuk menjalankan _formKey.currentState!.validate yang memeriksa seluruh TextFormField di dalam Form, dan apabila seluruh validasi bernilai true, nilai kedua kolom masukan diambil melalui properti text lalu ditampilkan melalui ScaffoldMessenger.of(context).showSnackBar berupa widget SnackBar bertuliskan pesan keberhasilan validasi.


G. Penambahan Controller pada Widget TextFormField

  1. Pada kedua widget TextFormField, ditambahkan properti controller yang masing-masing dihubungkan dengan _nameController dan _emailController, serta properti validator berupa fungsi yang memeriksa nilai masukan dan mengembalikan pesan kesalahan bila aturan tidak terpenuhi, atau null bila masukan dianggap sah.
  2. Pada TextFormField nama, validasi hanya memastikan nilai tidak bernilai null dan tidak kosong melalui isEmpty, sedangkan pada TextFormField email ditambahkan pemeriksaan lanjutan melalui method contains untuk memastikan masukan mengandung karakter "@", sehingga pesan "Email tidak valid" ditampilkan di bawah kolom masukan apabila format email tidak sesuai.

H. Pembungkusan Widget TextFormField dengan Widget Form

  1. Dilakukan pembungkusan dengan Widget Form pada method build terhadap keseluruhan widget. Di dalam widget form, dimasukkan argumen key dengan parameter _formkey.

I. Penambahan Method _SubmitForm pada Method onPressed Di Widget ElevatedButton

  1. Pada widget ElevatedButton yang dibungkus SizedBox dengan lebar double.infinity, properti onPressed diisi dengan referensi method _submitForm, sehingga proses validasi seluruh TextFormField beserta penampilan SnackBar dijalankan setiap kali tombol berlabel "Submit" ditekan.
  2. Output pada web:



J. Tugas Praktikum

  1. Dibuat file dart baru pada folder lib\ dengan nama tugas_kalkulator.dart.
  2. Pada method build kelas MyApp, dikembalikan widget MaterialApp sebagai root widget aplikasi, dengan properti home berisi Scaffold yang bagian appBar-nya menampilkan bilah judul bertuliskan "Kalkulator Df137" dan bagian body-nya diisi widget kustom Kalkulator.
  3. Kelas Kalkulator diturunkan dari StatefulWidget dan mengembalikan objek _KalkulatorState melalui method createState, karena nilai masukan, operasi terpilih, dan hasil perhitungan berubah selama aplikasi berjalan.
  4. Di dalam kelas _KalkulatorState dideklarasikan dua buah TextEditingController, yaitu _angka1Controller dan _angka2Controller, yang mengelola nilai pada masing-masing kolom masukan, ditambah variabel _aktif sebagai penanda controller yang sedang menerima ketikan, variabel _operasi yang menyimpan lambang operasi terpilih, dan variabel _hasil yang menyimpan hasil perhitungan.
  5. Method dispose ditimpa melalui anotasi @override untuk melepaskan kedua controller melalui pemanggilan dispose miliknya, lalu diteruskan dengan super.dispose agar tidak terjadi kebocoran memori ketika widget dihapus dari pohon widget.
  6. Method _ketik menambahkan karakter yang ditekan ke properti text pada controller yang sedang aktif, sehingga angka yang dipilih pengguna langsung tampil pada kolom masukan yang bersangkutan.
  7. Method _pilihOperasi menyimpan lambang operasi yang ditekan ke variabel _operasi dan memindahkan _aktif ke _angka2Controller, sedangkan method _bersihkan mengosongkan kedua kolom masukan melalui method clear serta mengembalikan seluruh variabel ke keadaan awal; keduanya dibungkus setState agar antarmuka dibangun ulang mengikuti perubahan state.
  8. Method _hitung mengubah isi kedua kolom masukan menjadi bilangan melalui double.tryParse, lalu memeriksa dua keadaan khusus, yaitu masukan yang tidak berupa bilangan dan pembagian dengan nol, sehingga pesan "Masukan tidak valid" atau "Tidak bisa dibagi nol" ditampilkan sebagai pengganti hasil.
  9. Apabila kedua masukan sah, percabangan switch memilih operasi kali, bagi, tambah, atau kurang sesuai nilai _operasi, kemudian hasilnya diubah menjadi bilangan bulat melalui toInt apabila tidak memiliki nilai desimal, dan nilai akhir tersebut disimpan ke _hasil melalui setState.
  10. Method _kolomAngka dibuat sebagai fungsi pembangun widget agar kedua kolom masukan tidak ditulis berulang, mengembalikan widget Expanded berisi TextField dengan properti controller, keyboardType bernilai TextInputType.number, textAlign rata kanan, decoration berisi InputDecoration berlabel sesuai argumen dengan bingkai OutlineInputBorder, serta onTap yang memindahkan _aktif ke controller yang disentuh pengguna.
  11. Method _tombol mengembalikan widget Expanded berisi ElevatedButton dengan gaya yang diatur melalui ElevatedButton.styleFrom, meliputi warna latar sesuai argumen dan sudut membulat melalui RoundedRectangleBorder, sedangkan method _tombolAngka dan _tombolOperasi memanggil kembali method tersebut dengan aksi _ketik dan _pilihOperasi, sehingga seluruh tombol memiliki bentuk yang seragam.
  12. Method _baris mengembalikan widget Expanded berisi Row dengan properti spacing sebagai jarak antartombol dan crossAxisAlignment bernilai CrossAxisAlignment.stretch, sehingga setiap baris tombol mengisi tinggi yang tersedia secara merata.
  13. Pada method build kelas _KalkulatorState, dikembalikan widget Padding sebesar 16 piksel yang membungkus Column penyusun seluruh antarmuka, dengan elemen pertama berupa Row berisi kedua kolom masukan yang dipisahkan widget Text penampil lambang operasi, disusul widget Text yang menampilkan hasil perhitungan dengan ukuran huruf 40 dan ketebalan FontWeight.bold.
  14. Elemen berikutnya berupa lima baris papan tombol yang dibangun melalui method _baris, memuat tombol angka 0 sampai 9 beserta tanda desimal, empat tombol operasi berwarna jingga, tombol "C" berwarna merah yang memanggil _bersihkan, serta tombol "=" berwarna hijau yang memanggil _hitung.
  15. Full Kode:







3. Results & Discussion

Hasil Tugas Praktikum


Tampilan dan operasi Kabataku:



4. Conclusion

Kesimpulan

Berdasarkan praktik yang telah dilakukan, dapat disimpulkan bahwa penerimaan masukan pada aplikasi Flutter dibangun melalui widget basic form yang ditempatkan di dalam StatefulWidget, karena isi kolom masukan beserta hasil pengolahannya merupakan state yang berubah selama aplikasi berjalan. Widget TextField berperan menampilkan kolom masukan yang tampilannya diatur melalui InputDecoration, sedangkan nilainya dikelola oleh TextEditingController dan dibaca melalui properti text, dengan method dispose yang wajib melepaskan controller tersebut agar tidak terjadi kebocoran memori. Widget TextFormField merupakan versi lengkap dari TextField yang terhubung dengan logika validasi melalui properti validator, sehingga pesan kesalahan ditampilkan secara otomatis di bawah kolom masukan apabila nilai yang dimasukkan tidak memenuhi aturan, seperti kolom kosong atau alamat surel tanpa karakter "@".


Pengendalian validasi secara kolektif dimungkinkan oleh GlobalKey<FormState> yang memberikan akses terhadap FormState dari luar widget Form, sehingga method validate dapat dipanggil dari fungsi onPressed pada ElevatedButton dan hasilnya disampaikan kepada pengguna melalui SnackBar yang dimunculkan oleh ScaffoldMessenger. Penerapan yang sama terlihat pada aplikasi kalkulator kabataku, yaitu nilai masukan dibaca dari controller, diperiksa kebenarannya melalui double.tryParse beserta penanganan pembagian dengan nol, lalu hasil perhitungannya diperbarui pada antarmuka melalui method setState. Dengan demikian, pemahaman terhadap alur menerima, memvalidasi, dan memperbarui masukan menjadi dasar penting dalam membangun aplikasi mobile yang mampu berinteraksi dengan pengguna secara benar dan terkendali


LINK GITHUB: https://github.com/DaffaAiraAdrn/Aplikasi_Mobile_26


← Back to Reports