Pada postingan kali ini tujuan saya adalah memperdalam pemahaman siswa tentang Widget Flutter, saya sarankan materi jangan langsung masuk ke kode yang kompleks. Siswa perlu memahami dulu bahwa Flutter hampir semuanya adalah Widget.
Berikut materi yang bisa langsung dijadikan bahan pembelajaran kelas XI PPLG.
MATERI PEMBELAJARAN FLUTTER — MEMAHAMI WIDGET
1. Apa itu Widget?
Widget adalah komponen pembentuk tampilan dan perilaku aplikasi Flutter.
Analogi sederhananya:
Kalau membuat rumah, maka Widget adalah bahan-bahan bangunannya.
Misalnya:
| Bagian aplikasi | Widget Flutter |
|---|---|
| Tulisan | Text |
| Tombol | ElevatedButton |
| Gambar | Image |
| Kotak/wadah | Container |
| Baris | Row |
| Kolom | Column |
| Jarak | SizedBox |
| Input teks | TextField |
| Checkbox | Checkbox |
| Switch | Switch |
| Ikon | Icon |
| Daftar | ListView |
| Kartu | Card |
| Halaman | Scaffold |
Konsep paling penting:
Flutter App
↓
MaterialApp
↓
Scaffold
↓
AppBar
↓
Body
↓
Column
├── Text
├── TextField
├── SizedBox
└── ElevatedButton
Jadi sebuah aplikasi sebenarnya merupakan susunan Widget di dalam Widget.
2. Dua Jenis Widget Utama
Flutter memiliki dua jenis widget yang sangat penting untuk dipahami siswa.
StatelessWidget
Widget yang tampilannya tidak memiliki perubahan state internal.
Contoh:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const Text(
'Halo Flutter',
);
}
}
Contoh penggunaan:
Judul
Logo
Icon
Tampilan informasi
Layout statis
StatefulWidget
Widget yang tampilannya dapat berubah karena adanya state.
Contoh:
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int counter = 0;
void tambah() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('$counter'),
ElevatedButton(
onPressed: tambah,
child: const Text('Tambah'),
),
],
);
}
}
Ketika tombol ditekan:
0
↓
1
↓
2
↓
3
Di sinilah siswa mulai memahami konsep state dan interaksi.
3. Widget Struktur Dasar Flutter
A. MaterialApp
MaterialApp biasanya menjadi widget paling luar aplikasi.
MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello Flutter'),
),
),
)
Tampilan:
┌─────────────────────────────┐
│ │
│ │
│ Hello Flutter │
│ │
│ │
└─────────────────────────────┘
4. Scaffold
Scaffold menyediakan struktur dasar halaman aplikasi.
Scaffold(
appBar: AppBar(
title: Text('Belajar Flutter'),
),
body: Center(
child: Text('Hello World'),
),
)
Strukturnya:
┌─────────────────────────────┐
│ Belajar Flutter │ ← AppBar
├─────────────────────────────┤
│ │
│ │
│ Hello World │ ← Body
│ │
│ │
└─────────────────────────────┘
Bagian penting:
Scaffold
├── appBar
├── body
├── floatingActionButton
├── drawer
├── bottomNavigationBar
└── bottomSheet
5. AppBar
Digunakan untuk membuat bagian atas aplikasi.
AppBar(
title: Text('Data Siswa'),
)
Tampilan:
┌─────────────────────────────┐
│ ← Data Siswa │
├─────────────────────────────┤
│ │
│ │
│ │
└─────────────────────────────┘
Bisa juga:
AppBar(
title: Text('Data Siswa'),
actions: [
Icon(Icons.search),
Icon(Icons.more_vert),
],
)
6. Text
Widget paling dasar untuk menampilkan tulisan.
Text(
'Belajar Flutter',
)
Dengan style:
Text(
'Belajar Flutter',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
)
Tampilan:
┌─────────────────────────────┐
│ │
│ Belajar Flutter │
│ │
└─────────────────────────────┘
Siswa perlu memahami:
fontSize
fontWeight
fontStyle
letterSpacing
color
7. Center
Untuk meletakkan widget di tengah.
Center(
child: Text('Hello'),
)
Tampilan:
┌─────────────────────────────┐
│ │
│ │
│ Hello │
│ │
│ │
└─────────────────────────────┘
Konsep:
Center
↓
child
↓
Text
8. Container
Container adalah widget yang sangat penting.
Bisa digunakan untuk:
ukuran
warna
margin
padding
border
radius
decoration
Contoh:
Container(
width: 200,
height: 100,
color: Colors.blue,
child: Center(
child: Text(
'Flutter',
style: TextStyle(
color: Colors.white,
),
),
),
)
Gambaran:
┌─────────────────────────────┐
│ │
│ ┌────────────┐ │
│ │ Flutter │ │
│ └────────────┘ │
│ │
└─────────────────────────────┘
Dengan decoration:
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.blue,
),
child: Text('Card Flutter'),
)
9. Padding
Memberikan ruang di dalam widget.
Padding(
padding: EdgeInsets.all(20),
child: Text('Hello'),
)
Konsep:
Container
┌─────────────────────────────┐
│ │
│ padding │
│ ↓ │
│ Hello │
│ │
└─────────────────────────────┘
Jenis padding:
EdgeInsets.all(20)
EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
)
EdgeInsets.only(
left: 20,
top: 10,
)
10. SizedBox
Digunakan untuk memberikan ukuran atau jarak.
Column(
children: [
Text('Nama'),
SizedBox(height: 20),
Text('Kelas'),
],
)
Tampilan:
Nama
Kelas
Contoh horizontal:
Row(
children: [
Text('Nama'),
SizedBox(width: 20),
Text('Darsu'),
],
)
11. Column
Menyusun widget secara vertikal.
Column(
children: [
Text('Nama'),
Text('Darsu'),
Text('PPLG'),
],
)
Tampilan:
Nama
Darsu
PPLG
Gambaran:
Column
│
├── Text
│
├── Text
│
└── Text
Properti penting:
mainAxisAlignment
crossAxisAlignment
Contoh:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Nama'),
Text('Darsu'),
],
)
12. Row
Menyusun widget secara horizontal.
Row(
children: [
Icon(Icons.home),
Text('Home'),
],
)
Tampilan:
🏠 Home
Contoh:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Harga'),
Text('Rp10.000'),
],
)
Tampilan:
Harga Rp10.000
13. Expanded
Digunakan agar widget mengambil ruang yang tersedia.
Row(
children: [
Expanded(
child: Container(
height: 100,
color: Colors.blue,
),
),
Expanded(
child: Container(
height: 100,
color: Colors.red,
),
),
],
)
Gambaran:
┌─────────────────────────────┐
│ │ │
│ Blue │ Red │
│ │ │
└─────────────────────────────┘
Sangat penting untuk memahami layout Flutter.
14. Flexible
Mirip Expanded, tetapi lebih fleksibel dalam penggunaan ruang.
Row(
children: [
Flexible(
child: Text(
'Ini adalah teks yang sangat panjang...',
),
),
],
)
Biasanya digunakan ketika teks atau widget harus menyesuaikan ruang yang tersedia.
15. Stack
Menyusun widget bertumpuk.
Stack(
children: [
Container(
width: 200,
height: 200,
color: Colors.blue,
),
Text('Flutter'),
],
)
Konsep:
┌─────────────────────┐
│ │
│ Flutter │
│ │
└─────────────────────┘
Contoh yang lebih menarik:
┌──────────────────────────┐
│ FOTO PRODUK │
│ │
│ SALE │
└──────────────────────────┘
Biasanya digunakan untuk:
badge
overlay
teks di atas gambar
tombol floating
16. Image
Menampilkan gambar.
Image.network(
'https://picsum.photos/300',
)
Atau asset:
Image.asset(
'assets/images/logo.png',
)
Tampilan:
┌─────────────────────────────┐
│ │
│ [ GAMBAR ] │
│ │
└─────────────────────────────┘
17. Icon
Menampilkan ikon.
Icon(
Icons.home,
)
Contoh:
Row(
children: [
Icon(Icons.person),
Text('Profil'),
],
)
Flutter menyediakan banyak ikon:
Icons.home
Icons.person
Icons.settings
Icons.search
Icons.favorite
Icons.delete
Icons.edit
Icons.add
Icons.menu
18. ElevatedButton
Tombol utama.
ElevatedButton(
onPressed: () {
print('Tombol ditekan');
},
child: Text('Simpan'),
)
Tampilan:
┌─────────────────────────────┐
│ │
│ ┌──────────┐ │
│ │ Simpan │ │
│ └──────────┘ │
│ │
└─────────────────────────────┘
19. TextButton
Tombol yang tampil lebih sederhana.
TextButton(
onPressed: () {},
child: Text('Lupa Password?'),
)
Biasanya digunakan untuk:
link
aksi sekunder
navigasi
20. OutlinedButton
Tombol dengan garis tepi.
OutlinedButton(
onPressed: () {},
child: Text('Batal'),
)
Gambaran:
┌─────────────────────────────┐
│ │
│ ┌──────────┐ │
│ │ Batal │ │
│ └──────────┘ │
│ │
└─────────────────────────────┘
21. FloatingActionButton
Tombol melayang.
FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
)
Biasanya muncul:
┌─────────────────────────────┐
│ │
│ │
│ │
│ ( + ) │
└─────────────────────────────┘
22. TextField
Widget untuk input teks.
TextField(
decoration: InputDecoration(
labelText: 'Nama',
hintText: 'Masukkan nama',
border: OutlineInputBorder(),
),
)
Tampilan:
┌─────────────────────────────┐
│ Nama │
│ Masukkan nama │
└─────────────────────────────┘
23. TextFormField
Digunakan terutama dalam Form.
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
),
)
Perbedaannya:
TextField
↓
Input sederhana
TextFormField
↓
Input + validasi Form
24. Checkbox
Untuk pilihan ya/tidak.
Checkbox(
value: true,
onChanged: (value) {},
)
Tampilan:
☑ Saya setuju
Contoh aplikasi:
Syarat & ketentuan
Pilihan fitur
Checklist tugas
25. Switch
Untuk mengaktifkan atau menonaktifkan sesuatu.
Switch(
value: true,
onChanged: (value) {},
)
Contoh:
Mode Gelap ON
[●──]
26. Radio
Memilih satu pilihan dari beberapa pilihan.
Jenis Kelamin
◉ Laki-laki
○ Perempuan
Contoh konsep:
Radio(
value: 'L',
groupValue: jenisKelamin,
onChanged: (value) {},
)
27. DropdownButton
Memilih data dari daftar.
Kelas
┌─────────────────────────┐
│ XI PPLG 1 ▼ │
└─────────────────────────┘
Contoh:
DropdownButton<String>(
value: 'XI PPLG 1',
items: [
DropdownMenuItem(
value: 'XI PPLG 1',
child: Text('XI PPLG 1'),
),
DropdownMenuItem(
value: 'XI PPLG 2',
child: Text('XI PPLG 2'),
),
],
onChanged: (value) {},
)
28. Card
Membuat tampilan seperti kartu.
Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text('Darsu'),
Text('XI PPLG 1'),
],
),
),
)
Gambaran:
┌─────────────────────────────┐
│ Darsu │
│ XI PPLG 1 │
└─────────────────────────────┘
Card sangat sering digunakan dalam aplikasi modern.
29. ListView
Untuk membuat daftar yang dapat di-scroll.
ListView(
children: [
ListTile(
title: Text('Andi'),
),
ListTile(
title: Text('Budi'),
),
ListTile(
title: Text('Citra'),
),
],
)
Tampilan:
┌─────────────────────────────┐
│ Daftar Siswa │
├─────────────────────────────┤
│ 👤 Andi │
├─────────────────────────────┤
│ 👤 Budi │
├─────────────────────────────┤
│ 👤 Citra │
├─────────────────────────────┤
│ 👤 Deni │
│ ↓ scroll │
└─────────────────────────────┘
30. ListTile
Widget khusus untuk membuat item daftar.
ListTile(
leading: Icon(Icons.person),
title: Text('Darsu'),
subtitle: Text('XI PPLG 1'),
trailing: Icon(Icons.arrow_forward_ios),
)
Tampilan:
👤 Darsu >
XI PPLG 1
Ini salah satu widget yang wajib dikuasai siswa.
31. Divider
Membuat garis pemisah.
Divider()
Contoh:
Nama : Darsu
────────────────────────
Kelas : XI PPLG 1
32. CircleAvatar
Membuat avatar berbentuk lingkaran.
CircleAvatar(
child: Text('D'),
)
Tampilan:
◯
D
Biasanya digunakan untuk:
profil
daftar pengguna
komentar
chat
33. Badge
Untuk menampilkan indikator kecil.
Contoh konsep:
🔔 ³
Misalnya notifikasi:
🔔
3
Sangat cocok untuk aplikasi modern.
34. BottomNavigationBar
Navigasi bagian bawah.
Contoh:
┌─────────────────────────────┐
│ │
│ Dashboard │
│ │
├─────────────────────────────┤
│ 🏠 📋 👤 ⚙️ │
│ Home Data Profil Setting
└─────────────────────────────┘
Digunakan pada aplikasi yang memiliki beberapa halaman utama.
35. Drawer
Menu yang muncul dari samping.
┌───────────────┬─────────────┐
│ 👤 Darsu │ │
│ │ │
│ 🏠 Home │ │
│ 👥 Siswa │ │
│ 📚 Materi │ │
│ ⚙️ Setting │ │
│ │ │
└───────────────┴─────────────┘
36. Dialog
Menampilkan pesan atau konfirmasi.
Contoh:
┌─────────────────────────────┐
│ Hapus Data? │
│ │
│ Apakah Anda yakin? │
│ │
│ BATAL HAPUS │
└─────────────────────────────┘
Digunakan untuk:
konfirmasi
informasi
peringatan
input sederhana
37. SnackBar
Pesan sementara di bagian bawah.
Contoh:
┌─────────────────────────────┐
│ │
│ │
│ Data berhasil disimpan │
└─────────────────────────────┘
Misalnya:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Data berhasil disimpan'),
),
);
38. ProgressIndicator
Menampilkan proses.
Circular:
◌
Loading...
Contoh:
CircularProgressIndicator()
Linear:
████████████░░░░░
Contoh:
LinearProgressIndicator(
value: 0.7,
)
39. Wrap
Mirip Row, tetapi widget akan otomatis turun ke baris berikutnya jika tidak cukup ruang.
Wrap(
spacing: 8,
children: [
Chip(label: Text('Flutter')),
Chip(label: Text('Dart')),
Chip(label: Text('Firebase')),
Chip(label: Text('SQLite')),
],
)
Tampilan:
┌─────────────────────────────┐
│ [Flutter] [Dart] │
│ [Firebase] [SQLite] │
└─────────────────────────────┘
40. SafeArea
Mencegah konten tertutup oleh notch, status bar, atau area sistem.
SafeArea(
child: Text('Hello Flutter'),
)
Sangat penting pada aplikasi mobile.
41. SingleChildScrollView
Membuat halaman dapat di-scroll.
SingleChildScrollView(
child: Column(
children: [
Text('Materi 1'),
Text('Materi 2'),
Text('Materi 3'),
Text('Materi 4'),
],
),
)
42. GridView
Menampilkan data berbentuk grid.
Contoh:
┌──────────┬──────────┐
│ 📱 │ 💻 │
│ Mobile │ Desktop │
├──────────┼──────────┤
│ 🌐 │ 🗄️ │
│ Web │ Database │
└──────────┴──────────┘
Cocok untuk:
katalog
menu aplikasi
dashboard
galeri
43. Widget yang Sebaiknya Dikuasai Siswa
Saya sarankan jangan memberikan 40 widget sekaligus untuk dihafalkan.
Buat level penguasaan.
LEVEL 1 — Fundamental
Siswa wajib menguasai:
Text
Icon
Image
Container
Center
Padding
SizedBox
LEVEL 2 — Layout
Kemudian:
Row
Column
Expanded
Flexible
Stack
Wrap
LEVEL 3 — Interaction
Kemudian:
ElevatedButton
TextButton
OutlinedButton
TextField
TextFormField
Checkbox
Radio
Switch
DropdownButton
LEVEL 4 — Data & List
Kemudian:
ListView
ListTile
GridView
Card
CircleAvatar
Divider
LEVEL 5 — Application Structure
Kemudian:
MaterialApp
Scaffold
AppBar
Drawer
BottomNavigationBar
FloatingActionButton
SafeArea
LEVEL 6 — Feedback
Kemudian:
Dialog
SnackBar
CircularProgressIndicator
LinearProgressIndicator
44. Tantangan Terbaik Untuk Siswa
Daripada siswa hanya mengetik contoh satu-satu, saya sarankan diberikan satu desain aplikasi kemudian mereka membedah Widget-nya.
Misalnya aplikasi sederhana:
┌─────────────────────────────┐
│ ← PROFIL SISWA │
├─────────────────────────────┤
│ │
│ ◯ │
│ D │
│ │
│ DARSU │
│ XI PPLG 1 │
│ │
│ ┌─────────────────────────┐ │
│ │ NIS │ │
│ │ 123456 │ │
│ └─────────────────────────┘ │
│ │
│ ┌─────────────────────────┐ │
│ │ Kelas │ │
│ │ XI PPLG 1 │ │
│ └─────────────────────────┘ │
│ │
│ ┌──────────────┐ │
│ │ EDIT │ │
│ └──────────────┘ │
│ │
└─────────────────────────────┘
Kemudian tanyakan:
"Widget apa saja yang digunakan untuk membuat tampilan tersebut?"
Jawaban yang diharapkan:
Scaffold
├── AppBar
│ └── Text
│
└── Body
└── SingleChildScrollView
└── Column
├── CircleAvatar
├── Text
├── Text
├── Card
│ └── Column
│ ├── Text
│ └── Text
│
├── Card
│ └── Column
│
└── ElevatedButton
Ini jauh lebih bagus untuk pemahaman siswa daripada sekadar menghafal nama widget.
45. Konsep Utama yang Harus Masuk ke Kepala Siswa
Saya akan tekankan 5 kalimat berikut kepada siswa:
1. Flutter adalah Widget
Hampir semua yang kita lihat dalam aplikasi Flutter adalah Widget.
2. Widget dapat memiliki Widget lain
Container(
child: Text('Hello'),
)
Artinya:
Container
└── Text
3. Widget dapat disusun
Column(
children: [
Text(),
Text(),
ElevatedButton(),
],
)
4. Widget mempunyai property
Contoh:
Text(
'Hello',
style: TextStyle(
fontSize: 24,
),
)
5. Widget dapat memiliki perilaku
ElevatedButton(
onPressed: () {
print('Klik');
},
child: Text('Klik Saya'),
)
Jadi siswa akhirnya memahami:
WIDGET
│
├── Child
│
├── Property
│
├── Style
│
└── Behavior
Urutan pembelajaran yang saya rekomendasikan
Untuk kelas XI PPLG, saya akan membawanya seperti ini:
PERTEMUAN 1
Apa itu Widget?
↓
Text, Icon, Image
↓
Container
↓
Center
PERTEMUAN 2
Row
Column
SizedBox
Padding
Expanded
Flexible
Stack
Wrap
PERTEMUAN 3
Button
TextField
Checkbox
Radio
Switch
Dropdown
PERTEMUAN 4
Card
ListView
ListTile
GridView
CircleAvatar
PERTEMUAN 5
Scaffold
AppBar
Drawer
FAB
BottomNavigationBar
Dialog
SnackBar
PERTEMUAN 6
Mini Project
"Student Profile App"
↓
Siswa membangun UI
↓
Menganalisis Widget Tree
↓
Presentasi
Kunci pedagogisnya: jangan hanya mengajarkan "ini kode Container". Biasakan siswa melihat desain → memecah desain menjadi widget → membuat widget tree → baru menulis kode.
Kalau pola ini dipakai, siswa akan lebih mudah ketika nanti masuk ke CRUD, SQLite/Firebase, API, dan aplikasi Flutter yang lebih kompleks, karena mereka sudah memahami fondasi layout dan widget.









