Aplikasi CRUD Jadwal perlajaran
Membuat Aplikasi Jadwal Pelajaran Modern dengan Flutter
Halo sobat developer! Hari ini kita akan membahas bagaimana cara membangun aplikasi Jadwal Pelajaran yang interaktif menggunakan Flutter. Aplikasi ini bukan sekadar daftar statis, tapi sudah dilengkapi dengan fungsi CRUD (Create, Read, Update, Delete) serta fitur pencarian dan filter hari.
Fitur Utama Aplikasi:
- ✅ Manajemen Data: Tambah, edit, dan hapus jadwal dengan mudah.
- 🔍 Fitur Pencarian: Cari mata pelajaran tertentu secara real-time.
- 📅 Filter Hari: Kelompokkan jadwal berdasarkan hari menggunakan FilterChip.
- 📊 Statistik Ringkas: Pantau jumlah total jadwal dan tugas yang sudah selesai.
- 🎨 UI Modern: Menggunakan tema warna Indigo yang profesional dan bersih.
Source Code Lengkap
Silakan salin kode di bawah ini ke dalam file main.dart di proyek Flutter Anda:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Jadwal Pelajaran',
theme: ThemeData(primarySwatch: Colors.indigo),
home: JadwalPage(),
);
}
}
class Jadwal {
String nama;
String hari;
String waktu;
bool isCompleted;
Jadwal({
required this.nama,
required this.hari,
required this.waktu,
this.isCompleted = false,
});
}
class JadwalPage extends StatefulWidget {
@override
_JadwalPageState createState() => _JadwalPageState();
}
class _JadwalPageState extends State<JadwalPage> {
List<Jadwal> jadwalList = [];
String searchQuery = '';
String filterHari = 'Semua';
final List<String> daftarHari = [
'Semua', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu',
];
void tambahData(Jadwal jadwal) {
setState(() {
jadwalList.add(jadwal);
});
}
void editData(int index, Jadwal jadwalBaru) {
setState(() {
jadwalList[index] = jadwalBaru;
});
}
void hapusData(int index) {
setState(() {
jadwalList.removeAt(index);
});
}
void toggleComplete(int index) {
setState(() {
jadwalList[index].isCompleted = !jadwalList[index].isCompleted;
});
}
void tampilDialog({Jadwal? jadwalLama, int? index}) {
final isEditing = jadwalLama != null;
TextEditingController namaController = TextEditingController(text: jadwalLama?.nama ?? "");
String selectedHari = jadwalLama?.hari ?? 'Senin';
String selectedWaktu = jadwalLama?.waktu ?? '08:00';
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setStateDialog) {
return AlertDialog(
title: Text(isEditing ? "Edit Jadwal" : "Tambah Jadwal Baru"),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: namaController,
decoration: InputDecoration(
labelText: "Mata Pelajaran",
prefixIcon: Icon(Icons.book),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
),
),
SizedBox(height: 16),
DropdownButtonFormField<String>(
value: selectedHari,
items: daftarHari.where((h) => h != 'Semua').map((hari) {
return DropdownMenuItem(value: hari, child: Text(hari));
}).toList(),
onChanged: (val) => setStateDialog(() => selectedHari = val!),
decoration: InputDecoration(
labelText: "Hari",
prefixIcon: Icon(Icons.calendar_today),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
),
),
SizedBox(height: 16),
TextField(
controller: TextEditingController(text: selectedWaktu),
onChanged: (val) => selectedWaktu = val,
decoration: InputDecoration(
labelText: "Waktu",
prefixIcon: Icon(Icons.access_time),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
),
),
],
),
),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: Text("Batal")),
ElevatedButton(
onPressed: () {
if (namaController.text.isNotEmpty) {
final baru = Jadwal(nama: namaController.text, hari: selectedHari, waktu: selectedWaktu);
isEditing ? editData(index!, baru) : tambahData(baru);
Navigator.pop(context);
}
},
child: Text("Simpan"),
),
],
);
},
);
},
);
}
@override
Widget build(BuildContext context) {
final filtered = jadwalList.where((j) {
final matchesSearch = j.nama.toLowerCase().contains(searchQuery.toLowerCase());
final matchesHari = filterHari == 'Semua' || j.hari == filterHari;
return matchesSearch && matchesHari;
}).toList();
return Scaffold(
appBar: AppBar(
title: Text("Jadwal Pelajaran"),
backgroundColor: Colors.indigo,
bottom: PreferredSize(
preferredSize: Size.fromHeight(60),
child: Container(
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: daftarHari.length,
itemBuilder: (context, i) => Padding(
padding: EdgeInsets.symmetric(horizontal: 4),
child: FilterChip(
label: Text(daftarHari[i]),
selected: filterHari == daftarHari[i],
onSelected: (val) => setState(() => filterHari = daftarHari[i]),
),
),
),
),
),
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(16),
child: TextField(
onChanged: (val) => setState(() => searchQuery = val),
decoration: InputDecoration(
hintText: "Cari mata pelajaran...",
prefixIcon: Icon(Icons.search),
filled: true,
fillColor: Colors.grey[100],
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none),
),
),
),
Expanded(
child: ListView.builder(
itemCount: filtered.length,
itemBuilder: (context, i) {
final item = filtered[i];
return Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ListTile(
leading: CircleAvatar(
backgroundColor: item.isCompleted ? Colors.green : Colors.indigo,
child: Icon(item.isCompleted ? Icons.check : Icons.book, color: Colors.white),
),
title: Text(item.nama, style: TextStyle(
decoration: item.isCompleted ? TextDecoration.lineThrough : null,
fontWeight: FontWeight.bold
)),
subtitle: Text("${item.hari} | ${item.waktu}"),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(icon: Icon(Icons.check_circle, color: Colors.green), onPressed: () => toggleComplete(jadwalList.indexOf(item))),
IconButton(icon: Icon(Icons.delete, color: Colors.red), onPressed: () => hapusData(jadwalList.indexOf(item))),
],
),
),
);
},
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => tampilDialog(),
child: Icon(Icons.add),
backgroundColor: Colors.indigo,
),
);
}
}
Kesimpulan
Dengan kode ini, Anda telah berhasil membuat aplikasi manajemen jadwal yang fungsional dan memiliki tampilan menarik. Flutter memudahkan kita mengelola state (data) sehingga fitur seperti filter dan pencarian bisa berjalan dengan sangat mulus.
Tips: Anda bisa mengembangkan aplikasi ini lebih lanjut dengan menambahkan fitur database lokal seperti Sqflite atau Shared Preferences agar data tidak hilang saat aplikasi ditutup.
Selamat mencoba dan Happy Coding! 🚀
Komentar
Posting Komentar