Konsep Dasar Input Widgets dan Form
Basic Form
Widget yang berfungsi sebagai inputan nilai seperti TextField, TextFormField, CheckBox, Switch, Dropdown, Radio, Dialog, DatePicker, BottomSheet, Snackbar. Digunakan untuk validasi dan mengelola inputan dari berbagai field.
TextField
Widget untuk memasukkan teks oleh pengguna, biasanya digunakan untuk form inputan seperti login, pencarian, dll. Menerima input dari keyboard dengan property lengkap untuk style, decoration, dan jenis inputan.
TextFormField
Versi lengkap dari TextField yang terintegrasi dengan logika validasi dan manajemen state dari sebuah form. Memiliki properti validator untuk memeriksa input sesuai aturan yang ditentukan.
GlobalKey & FormState
GlobalKey digunakan untuk mengidentifikasi dan mengakses state secara global. FormState mengelola status dari Form, seperti status validasi setiap inputan. Memungkinkan pemanggilan metode validate() atau save() dari luar widget.
Langkah Implementasi sesuai Modul
Basic Form dengan TextField
Langkah-langkah:
- Membuat file baru dengan nama form-textfield.dart
- Membuat tampilan basic form dengan Widget TextField dan ElevatedButton
- Menambahkan TextEditingController untuk mengelola inputan
- Menambahkan event listener pada TextField
- Menampilkan hasil input menggunakan SnackBar
Kode Implementasi:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Basic Form')),
body: const MyForm(),
),
);
}
}
class MyForm extends StatefulWidget {
const MyForm({super.key});
@override
State createState() => _MyFormState();
}
class _MyFormState extends State {
TextEditingController _textEditingController = TextEditingController();
String inputText = '';
@override
void dispose() {
_textEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Masukkan nama anda:'),
const SizedBox(height: 10),
TextField(
decoration: InputDecoration(
labelText: 'Nama lengkap',
hintText: 'John Doe',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
controller: _textEditingController,
keyboardType: TextInputType.text,
onChanged: (text) {
print('Sedang mengetik teks : ,$text');
},
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
inputText = _textEditingController.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Nama anda adalah, $inputText')),
);
setState(() {
inputText = _textEditingController.text;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.amber,
foregroundColor: Colors.black,
),
child: const Text('Tampilkan nama'),
),
SizedBox(height: 20),
Text('Nama Anda : $inputText', style: const TextStyle(fontSize: 20)),
],
),
);
}
}
Dokumentasi:
Gambar 1: Tampilan Basic Form dengan TextField
Basic Form dengan TextFormField
Langkah-langkah:
- Membuat file baru dengan nama form-textformfield.dart
- Membuat form dengan 2 TextFormField dan ElevatedButton
- Menggunakan GlobalKey untuk mengelola state form
- Menambahkan validator untuk validasi input
- Menampilkan pesan error jika validasi gagal
Kode Implementasi:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Basic Form TextFormField")),
body: const MyFormText(),
),
);
}
}
class MyFormText extends StatefulWidget {
const MyFormText({super.key});
@override
State createState() => _MyFormTextState();
}
class _MyFormTextState extends State {
final _formKey = GlobalKey();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
String name = _nameController.text;
String email = _emailController.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Validasi $name, $email Berhasil')),
);
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 10),
TextFormField(
controller: _nameController,
decoration: const InputDecoration(
labelText: "Nama : ",
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan nama anda';
}
return null;
},
),
const SizedBox(height: 10),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
labelText: "Email : ",
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan email anda';
}
if (!value.contains('@')) {
return 'Email tidak valid';
}
return null;
},
),
const SizedBox(height: 10),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _submitForm,
child: const Text('Submit'),
),
),
],
),
),
);
}
}
Dokumentasi:
Gambar 2: Tampilan Basic Form dengan TextFormField
Tugas: Aplikasi Kalkulator Kabataku
Implementasi Kalkulator Kabataku
Berdasarkan tugas pada modul, saya telah membuat aplikasi kalkulator yang dapat melakukan operasi kabataku (kali, bagi, tambah, kurang) menggunakan Flutter.
Fitur yang Diimplementasikan:
- 2 buah TextField untuk menerima input angka dari pengguna
- 4 buah ElevatedButton untuk operasi matematika (+, -, ×, ÷)
- Validasi input untuk memastikan angka yang dimasukkan valid
- Penanganan error untuk pembagian dengan nol
- Widget Text untuk menampilkan hasil perhitungan
Kode Implementasi:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Kabataku Kalkulator')),
body: const KabatakuCalculator(),
),
);
}
}
class KabatakuCalculator extends StatefulWidget {
const KabatakuCalculator({super.key});
@override
State createState() => _KabatakuCalculatorState();
}
class _KabatakuCalculatorState extends State {
final TextEditingController _controller1 = TextEditingController();
final TextEditingController _controller2 = TextEditingController();
String _result = '';
void _calculate(String operator) {
final num1 = double.tryParse(_controller1.text);
final num2 = double.tryParse(_controller2.text);
if (num1 == null || num2 == null) {
setState(() {
_result = 'Input tidak valid!';
});
return;
}
double hasil;
switch (operator) {
case '+':
hasil = num1 + num2;
break;
case '-':
hasil = num1 - num2;
break;
case '×':
hasil = num1 * num2;
break;
case '÷':
if (num2 == 0) {
_result = 'Tidak bisa dibagi 0!';
setState(() {});
return;
}
hasil = num1 / num2;
break;
default:
hasil = 0;
}
setState(() {
_result = 'Hasil: $hasil';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _controller1,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Angka pertama',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _controller2,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Angka kedua',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () => _calculate('+'),
child: const Text('+'),
),
ElevatedButton(
onPressed: () => _calculate('-'),
child: const Text('-'),
),
ElevatedButton(
onPressed: () => _calculate('×'),
child: const Text('×'),
),
ElevatedButton(
onPressed: () => _calculate('÷'),
child: const Text('÷'),
),
],
),
const SizedBox(height: 24),
Text(
_result,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
],
),
),
);
}
}
Penjelasan Kode:
- TextEditingController: Digunakan untuk mengambil nilai dari TextField
- _calculate(): Fungsi yang menangani logika perhitungan berdasarkan operator
- setState(): Memperbarui UI ketika hasil perhitungan berubah
- tryParse(): Mengonversi input string menjadi angka dengan penanganan error
- Validasi pembagian dengan nol: Mencegah error ketika pengguna mencoba membagi dengan nol
Dokumentasi:
Gambar 3: Tampilan Aplikasi Kalkulator Kabataku
Kesimpulan
Dalam praktikum ini, kita telah mempelajari:
- Perbedaan antara TextField dan TextFormField dalam Flutter
- Cara menggunakan TextEditingController untuk mengelola input dari pengguna
- Implementasi validasi form menggunakan GlobalKey dan FormState
- Pembuatan form yang interaktif dengan feedback menggunakan SnackBar
- Penerapan konsep-konsep tersebut dalam aplikasi kalkulator kabataku
Pemahaman tentang input widgets dan form management sangat penting dalam pengembangan aplikasi Flutter karena hampir setiap aplikasi memerlukan interaksi dengan pengguna melalui form input. Dengan menguasai konsep-konsep ini, kita dapat membuat aplikasi yang lebih interaktif dan user-friendly.
Untuk kode lengkap praktikum dan tugas dapat diakses pada repository GitHub: https://github.com/Alone1011/2311532011-RifkiY-MobileApp.git