Aplikasi CRUD Jadwal Pelajaran dengan Flutter
📱 Aplikasi CRUD Jadwal Pelajaran dengan Flutter
✨ Rekomendasi Terbaik untuk Manajemen Jadwal Sekolah
Kode Flutter lengkap untuk aplikasi CRUD (Create, Read, Update, Delete) jadwal pelajaran dengan fitur filter hari dan warna berbeda. Siap dijalankan di DartPad tanpa error!
🎯 Latar Belakang Kode Ini Direkomendasikan
📌 Mengapa Aplikasi Ini Penting?
- Efisiensi Manajemen Waktu - Membantu guru dan siswa mengatur jadwal pelajaran secara digital, mengurangi kesalahan pencatatan manual
- Visualisasi yang Jelas - Warna berbeda per hari memudahkan identifikasi jadwal secara cepat
- Fitur CRUD Lengkap - Pengguna dapat menambah, melihat, mengedit, dan menghapus jadwal dengan mudah
- Filter Cerdas - Filter berdasarkan hari membantu fokus pada jadwal tertentu tanpa kebingungan
- Responsif dan Modern - Menggunakan Flutter framework terbaru dengan Material Design 3
✅ Keunggulan Kode Ini
- ✅ Zero Error - Telah diuji dan siap jalan di DartPad
- ✅ Best Practice Flutter - Menggunakan StatefulWidget, setState(), dan manajemen state yang tepat
- ✅ User Friendly - UI intuitif dengan konfirmasi hapus dan notifikasi snackbar
- ✅ Kode Terstruktur - Mudah dipahami dan dikembangkan lebih lanjut
- ✅ Fitur Lengkap - CRUD + Filter + Warna + Validasi Form
🎨 Fitur Unggulan
| Fitur | Deskripsi |
|---|---|
| ➕ Create | Tambah jadwal baru dengan validasi form |
| 📖 Read | Tampilkan semua jadwal dalam list yang rapi |
| ✏️ Update | Edit jadwal yang sudah ada dengan mudah |
| 🗑️ Delete | Hapus jadwal dengan konfirmasi dialog |
| 🎨 Color Coding | Warna berbeda untuk setiap hari (Senin - Sabtu) |
| 🔍 Filter | Filter jadwal berdasarkan hari tertentu |
| 📱 Responsive | Tampilan optimal di berbagai ukuran layar |
🎨 Warna yang Digunakan per Hari
Senin - Merah Muda
Selasa - Oranye
Rabu - Kuning
Kamis - Hijau Muda
Jumat - Biru Muda
Sabtu - Ungu Muda
💻 Kode Flutter Lengkap
📌 Cara Menjalankan: Copy paste kode di bawah ke DartPad.dev dan klik Run. Pastikan memilih Flutter environment.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CRUD Jadwal Pelajaran',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: JadwalPelajaranPage(),
);
}
}
class JadwalPelajaran {
String id;
String namaMapel;
String hari;
String jamMulai;
String jamSelesai;
String ruangan;
JadwalPelajaran({
required this.id,
required this.namaMapel,
required this.hari,
required this.jamMulai,
required this.jamSelesai,
required this.ruangan,
});
}
class JadwalPelajaranPage extends StatefulWidget {
@override
_JadwalPelajaranPageState createState() => _JadwalPelajaranPageState();
}
class _JadwalPelajaranPageState extends State<JadwalPelajaranPage> {
List<JadwalPelajaran> daftarJadwal = [];
List<JadwalPelajaran> daftarJadwalFiltered = [];
final TextEditingController _namaMapelController = TextEditingController();
final TextEditingController _jamMulaiController = TextEditingController();
final TextEditingController _jamSelesaiController = TextEditingController();
final TextEditingController _ruanganController = TextEditingController();
String? _editId;
String _selectedFilterHari = 'Semua';
final List<String> daftarHari = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'];
String _selectedHari = 'Senin';
Color getColorForHari(String hari) {
switch (hari) {
case 'Senin':
return Colors.red[100]!;
case 'Selasa':
return Colors.orange[100]!;
case 'Rabu':
return Colors.yellow[100]!;
case 'Kamis':
return Colors.green[100]!;
case 'Jumat':
return Colors.blue[100]!;
case 'Sabtu':
return Colors.purple[100]!;
default:
return Colors.grey[100]!;
}
}
void filterJadwal() {
setState(() {
if (_selectedFilterHari == 'Semua') {
daftarJadwalFiltered = List.from(daftarJadwal);
} else {
daftarJadwalFiltered = daftarJadwal
.where((jadwal) => jadwal.hari == _selectedFilterHari)
.toList();
}
});
}
@override
void initState() {
super.initState();
daftarJadwal.add(JadwalPelajaran(
id: DateTime.now().millisecondsSinceEpoch.toString(),
namaMapel: 'Matematika',
hari: 'Senin',
jamMulai: '07:00',
jamSelesai: '08:30',
ruangan: 'R.101',
));
daftarJadwal.add(JadwalPelajaran(
id: DateTime.now().millisecondsSinceEpoch.toString() + '1',
namaMapel: 'Bahasa Indonesia',
hari: 'Selasa',
jamMulai: '09:00',
jamSelesai: '10:30',
ruangan: 'R.102',
));
filterJadwal();
}
void tambahAtauUpdateJadwal() {
if (_namaMapelController.text.isEmpty ||
_jamMulaiController.text.isEmpty ||
_jamSelesaiController.text.isEmpty ||
_ruanganController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Harap isi semua field!')),
);
return;
}
setState(() {
if (_editId == null) {
JadwalPelajaran jadwalBaru = JadwalPelajaran(
id: DateTime.now().millisecondsSinceEpoch.toString(),
namaMapel: _namaMapelController.text,
hari: _selectedHari,
jamMulai: _jamMulaiController.text,
jamSelesai: _jamSelesaiController.text,
ruangan: _ruanganController.text,
);
daftarJadwal.add(jadwalBaru);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Jadwal berhasil ditambahkan!')),
);
} else {
int index = daftarJadwal.indexWhere((j) => j.id == _editId);
if (index != -1) {
daftarJadwal[index] = JadwalPelajaran(
id: _editId!,
namaMapel: _namaMapelController.text,
hari: _selectedHari,
jamMulai: _jamMulaiController.text,
jamSelesai: _jamSelesaiController.text,
ruangan: _ruanganController.text,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Jadwal berhasil diupdate!')),
);
}
_editId = null;
}
_namaMapelController.clear();
_jamMulaiController.clear();
_jamSelesaiController.clear();
_ruanganController.clear();
_selectedHari = 'Senin';
filterJadwal();
});
}
void editJadwal(JadwalPelajaran jadwal) {
setState(() {
_editId = jadwal.id;
_namaMapelController.text = jadwal.namaMapel;
_selectedHari = jadwal.hari;
_jamMulaiController.text = jadwal.jamMulai;
_jamSelesaiController.text = jadwal.jamSelesai;
_ruanganController.text = jadwal.ruangan;
});
}
void hapusJadwal(String id) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Konfirmasi Hapus'),
content: Text('Apakah Anda yakin ingin menghapus jadwal ini?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Batal'),
),
TextButton(
onPressed: () {
setState(() {
daftarJadwal.removeWhere((j) => j.id == id);
filterJadwal();
});
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Jadwal berhasil dihapus!')),
);
},
child: Text('Hapus', style: TextStyle(color: Colors.red)),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('CRUD Jadwal Pelajaran'),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: Column(
children: [
Container(
padding: EdgeInsets.all(12),
color: Colors.grey[50],
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Filter Berdasarkan Hari:',
style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
FilterChip(
label: Text('Semua'),
selected: _selectedFilterHari == 'Semua',
onSelected: (selected) {
setState(() {
_selectedFilterHari = 'Semua';
filterJadwal();
});
},
),
SizedBox(width: 8),
...daftarHari.map((hari) {
return Padding(
padding: EdgeInsets.only(right: 8),
child: FilterChip(
label: Text(hari),
selected: _selectedFilterHari == hari,
onSelected: (selected) {
setState(() {
_selectedFilterHari = selected ? hari : 'Semua';
filterJadwal();
});
},
backgroundColor: getColorForHari(hari),
),
);
}),
],
),
),
],
),
),
Container(
padding: EdgeInsets.all(16),
color: Colors.grey[100],
child: Column(
children: [
TextField(
controller: _namaMapelController,
decoration: InputDecoration(
labelText: 'Nama Mata Pelajaran',
border: OutlineInputBorder(),
),
),
SizedBox(height: 12),
DropdownButtonFormField<String>(
value: _selectedHari,
decoration: InputDecoration(
labelText: 'Hari',
border: OutlineInputBorder(),
),
items: daftarHari.map((String hari) {
return DropdownMenuItem<String>(
value: hari,
child: Row(
children: [
Container(
width: 20,
height: 20,
color: getColorForHari(hari),
),
SizedBox(width: 8),
Text(hari),
],
),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
_selectedHari = newValue!;
});
},
),
SizedBox(height: 12),
Row(
children: [
Expanded(
child: TextField(
controller: _jamMulaiController,
decoration: InputDecoration(
labelText: 'Jam Mulai',
border: OutlineInputBorder(),
),
),
),
SizedBox(width: 12),
Expanded(
child: TextField(
controller: _jamSelesaiController,
decoration: InputDecoration(
labelText: 'Jam Selesai',
border: OutlineInputBorder(),
),
),
),
],
),
SizedBox(height: 12),
TextField(
controller: _ruanganController,
decoration: InputDecoration(
labelText: 'Ruangan',
border: OutlineInputBorder(),
),
),
SizedBox(height: 16),
ElevatedButton.icon(
onPressed: tambahAtauUpdateJadwal,
icon: Icon(_editId == null ? Icons.add : Icons.update),
label: Text(_editId == null ? 'Tambah Jadwal' : 'Update Jadwal'),
),
if (_editId != null)
TextButton(
onPressed: () {
setState(() {
_editId = null;
_namaMapelController.clear();
_jamMulaiController.clear();
_jamSelesaiController.clear();
_ruanganController.clear();
_selectedHari = 'Senin';
});
},
child: Text('Batal Edit'),
),
],
),
),
Expanded(
child: daftarJadwalFiltered.isEmpty
? Center(child: Text('Tidak ada jadwal'))
: ListView.builder(
itemCount: daftarJadwalFiltered.length,
itemBuilder: (context, index) {
final jadwal = daftarJadwalFiltered[index];
return Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
color: getColorForHari(jadwal.hari),
child: ListTile(
title: Text(jadwal.namaMapel,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${jadwal.hari}, ${jadwal.jamMulai} - ${jadwal.jamSelesai}'),
Text('Ruangan: ${jadwal.ruangan}'),
],
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit, color: Colors.blue),
onPressed: () => editJadwal(jadwal),
),
IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () => hapusJadwal(jadwal.id),
),
],
),
),
);
},
),
),
],
),
);
}
}
📚 Penjelasan Teknis
🔧 Fungsi-fungsi Penting:
- ListView.builder - Menampilkan daftar jadwal secara efisien dengan hanya me-render item yang terlihat
- tambahAtauUpdateJadwal() - Menangani operasi Create dan Update dalam satu fungsi
- hapusJadwal() - Menghapus data dengan konfirmasi dialog
- setState() - Memberi tahu Flutter bahwa ada perubahan data sehingga UI perlu di-rebuild
- filterJadwal() - Menyaring jadwal berdasarkan hari yang dipilih
🚀 Cara Menggunakan
- Buka DartPad.dev
- Pilih environment "Flutter"
- Copy paste seluruh kode di atas
- Klik tombol "Run"
- Aplikasi akan berjalan dan siap digunakan
💡 Tips Pengembangan Lebih Lanjut
- Tambahkan database lokal (SQLite/Hive) untuk menyimpan data secara permanen
- Integrasikan dengan Google Calendar API untuk sinkronisasi jadwal
- Tambahkan fitur reminder/notifikasi sebelum jam pelajaran dimulai
- Buat fitur export ke PDF untuk mencetak jadwal
- Tambahkan autentikasi user untuk multi-user (guru/murid)
📊 Perbandingan dengan Aplikasi Lain
| Fitur | Aplikasi Ini | Aplikasi Manual/Excel | Aplikasi Lain |
|---|---|---|---|
| CRUD Lengkap | ✅ | ❌ | ✅ |
| Filter Hari | ✅ | ❌ | ⚠️ Terbatas |
| Color Coding | ✅ | ⚠️ Manual | ❌ |
| Responsive | ✅ | ❌ | ⚠️ |
| Gratis & Open Source | ✅ | ✅ | ❌ Berbayar |
🎉 Kesimpulan
Kode Flutter CRUD Jadwal Pelajaran ini adalah solusi terbaik untuk manajemen jadwal sekolah yang modern, efisien, dan mudah digunakan. Dengan fitur lengkap, tampilan menarik, dan kode yang terstruktur, aplikasi ini sangat direkomendasikan untuk guru, siswa, dan developer yang ingin belajar Flutter.
Rating: ⭐⭐⭐⭐⭐ (5/5) - Recommended!
Komentar
Posting Komentar