Dari Struktur Kontrol Menuju Aplikasi Nyata

 Modul praktikum lengkap dalam format postingan blog yang juga bisa berfungsi sebagai LKPD (Lembar Kerja Peserta Didik) untuk siswa.


Materi ini adalah kelanjutan langsung dari Struktur Kontrol yang sudah dipelajari, dengan urutan yang sangat sistematis dan aplikatif untuk pemula Flutter.



🚀 MODUL PRAKTIKUM FLUTTER LANJUTAN

📚 Dari Struktur Kontrol Menuju Aplikasi Nyata

Untuk Siswa SMK Kelas XI RPL/PPLG

Oleh: [Nama Guru/Pengajar]
Tanggal: [Tanggal Posting]
Level: Pemula → Menengah
Durasi: ± 10–12 JP


🎯 Tujuan Pembelajaran Modul Ini

Setelah menyelesaikan seluruh praktikum, siswa diharapkan mampu:

  1. Menggunakan List, Map, dan Set untuk menyimpan data kolektif.

  2. Membuat fungsi sendiri untuk menyusun logika program.

  3. Membuat Class & Object untuk memodelkan data siswa.

  4. Mengelola state dengan setState dan memahami dasar Provider.

  5. Membuat navigasi antar halaman di Flutter.

  6. Menyimpan data dengan SharedPreferences (local storage).

  7. Membangun aplikasi CRUD (Create, Read, Update, Delete) sederhana.


📋 Prasyarat

Sebelum mengerjakan modul ini, pastikan kalian sudah:

✅ Memahami Struktur Kontrol (if, switch, for, while, break, continue, nested loop).
✅ Bisa membuat UI sederhana Flutter (TextField, Button, Card, ListView).
✅ Mengerti setState untuk update UI.


🧪 PRAKTIKUM 1 — KOLEKSI DATA (LIST, MAP, SET)


📖 Teori Singkat

Di Dart, ada 3 jenis koleksi data utama:

KoleksiPenjelasanContoh
ListKumpulan data berurutan (seperti array)['Andi', 'Budi', 'Citra']
MapPasangan key-value{'nama': 'Andi', 'nilai': 85}
SetKumpulan data unik (tanpa duplikat){1, 2, 3, 4}

🟢 Praktikum 1A — List & For Each

Tujuan

Siswa dapat membuat daftar siswa dan menampilkannya dengan berbagai cara.

Kode Dasar

dart
void main() {
  List<String> siswa = ['Andi', 'Budi', 'Citra', 'Dina', 'Eko'];
  
  // Cara 1: for loop
  for (int i = 0; i < siswa.length; i++) {
    print(siswa[i]);
  }
  
  // Cara 2: for-in
  for (String nama in siswa) {
    print(nama);
  }
  
  // Cara 3: forEach
  siswa.forEach((nama) {
    print(nama);
  });
}

✏️ Latihan 1A

  1. Buat daftar nilai 5 siswa: [80, 75, 90, 65, 88]

  2. Tampilkan semua nilai.

  3. Hitung dan tampilkan rata-rata nilai.

  4. Tampilkan nilai tertinggi dan nilai terendah.

dart
// Kunci Jawaban (sembunyikan untuk siswa)
void main() {
  List<int> nilai = [80, 75, 90, 65, 88];
  int total = 0;
  int tertinggi = nilai[0];
  int terendah = nilai[0];
  
  for (int n in nilai) {
    total += n;
    if (n > tertinggi) tertinggi = n;
    if (n < terendah) terendah = n;
  }
  
  print('Nilai: $nilai');
  print('Rata-rata: ${total / nilai.length}');
  print('Tertinggi: $tertinggi');
  print('Terendah: $terendah');
}

🟢 Praktikum 1B — Map untuk Data Siswa

Tujuan

Siswa dapat menggunakan Map untuk menyimpan data siswa yang lebih kompleks.

Kode Dasar

dart
void main() {
  Map<String, dynamic> siswa1 = {
    'nama': 'Andi',
    'tugas': 80,
    'uts': 75,
    'uas': 90,
  };
  
  print('Nama: ${siswa1['nama']}');
  print('Nilai Akhir: ${(siswa1['tugas'] * 0.3) + (siswa1['uts'] * 0.3) + (siswa1['uas'] * 0.4)}');
}

✏️ Latihan 1B

Buat List of Map untuk 3 siswa dengan data:

  • Nama

  • Tugas

  • UTS

  • UAS

Kemudian:

  1. Tampilkan semua data siswa.

  2. Tampilkan nilai akhir setiap siswa.

  3. Tampilkan predikat (A/B/C/D/E) setiap siswa (gunakan fungsi IF dari materi sebelumnya).


🟢 Praktikum 1C — Set (Data Unik)

Tujuan

Siswa memahami kegunaan Set untuk menghindari duplikasi data.

Kode Dasar

dart
void main() {
  Set<String> kelas = {'RPL 1', 'RPL 2', 'RPL 1', 'RPL 3'};
  print(kelas); // Output: {RPL 1, RPL 2, RPL 3} (duplikat hilang)
  
  kelas.add('RPL 4');
  print(kelas.contains('RPL 2')); // true
}

✏️ Latihan 1C

  1. Buat program yang menerima daftar nama siswa (boleh ada duplikat).

  2. Tampilkan daftar siswa tanpa duplikat menggunakan Set.

  3. Contoh:

text
Input: ['Andi', 'Budi', 'Andi', 'Citra', 'Budi']
Output: {Andi, Budi, Citra}

🧪 PRAKTIKUM 2 — FUNGSI / METHOD


📖 Teori Singkat

Fungsi adalah blok kode yang bisa dipanggil berkali-kali. Fungsi membantu:

  • Menghindari duplikasi kode

  • Membuat program lebih terstruktur

  • Memudahkan debugging


🟢 Praktikum 2A — Fungsi Sederhana

Kode Dasar

dart
// Fungsi tanpa parameter
void sapa() {
  print('Halo, selamat belajar Flutter!');
}

// Fungsi dengan parameter
void sapaNama(String nama) {
  print('Halo, $nama!');
}

// Fungsi dengan return value
int tambah(int a, int b) {
  return a + b;
}

void main() {
  sapa();
  sapaNama('Andi');
  print(tambah(5, 3));
}

✏️ Latihan 2A

Buat fungsi-fungsi berikut:

  1. hitungNilaiAkhir(tugas, uts, uas) → mengembalikan nilai akhir (double)

  2. predikat(nilaiAkhir) → mengembalikan predikat A-E (String)

  3. statusKelulusan(nilaiAkhir) → mengembalikan "LULUS" atau "TIDAK LULUS"

  4. Panggil fungsi-fungsi tersebut untuk data siswa.


🟢 Praktikum 2B — Fungsi sebagai Parameter & Arrow Function

Kode Dasar

dart
// Fungsi sebagai parameter
void prosesData(List<int> data, Function(int) proses) {
  for (int item in data) {
    proses(item);
  }
}

// Arrow function (=>) untuk fungsi satu baris
int kuadrat(int x) => x * x;

void main() {
  List<int> nilai = [10, 20, 30];
  
  prosesData(nilai, (item) {
    print('Data: $item');
  });
  
  print(kuadrat(5)); // 25
}

✏️ Latihan 2B

Buat program dengan:

  1. Fungsi filterNilai(List<int> nilai, Function filter) yang mengembalikan list nilai yang sudah difilter.

  2. Gunakan fungsi tersebut untuk:

    • Menampilkan nilai >= 75

    • Menampilkan nilai < 75


🧪 PRAKTIKUM 3 — CLASS & OBJECT (OOP DASAR)


📖 Teori Singkat

Class adalah "cetakan" untuk membuat object. Flutter sendiri berbasis OOP (semua Widget adalah class).


🟢 Praktikum 3 — Membuat Class Siswa

Kode Dasar

dart
class Siswa {
  // Property/Atribut
  String nama;
  double tugas;
  double uts;
  double uas;
  
  // Constructor
  Siswa(this.nama, this.tugas, this.uts, this.uas);
  
  // Method
  double get nilaiAkhir {
    return (tugas * 0.3) + (uts * 0.3) + (uas * 0.4);
  }
  
  String get predikat {
    double na = nilaiAkhir;
    if (na >= 90) return 'A';
    else if (na >= 80) return 'B';
    else if (na >= 70) return 'C';
    else if (na >= 60) return 'D';
    else return 'E';
  }
  
  String get status => nilaiAkhir >= 75 ? 'LULUS' : 'TIDAK LULUS';
  
  
  String toString() {
    return 'Nama: $nama, NA: ${nilaiAkhir.toStringAsFixed(1)}, Predikat: $predikat, Status: $status';
  }
}

void main() {
  Siswa andi = Siswa('Andi', 80, 75, 90);
  print(andi);
}

✏️ Latihan 3

  1. Buat class Siswa seperti di atas.

  2. Buat 5 object siswa dengan data berbeda.

  3. Simpan dalam List<Siswa>.

  4. Tampilkan data semua siswa.

  5. Tampilkan rata-rata nilai akhir semua siswa.

  6. Tampilkan siswa dengan nilai tertinggi.

dart
// Tambahan untuk latihan
void main() {
  List<Siswa> daftar = [
    Siswa('Andi', 80, 75, 90),
    Siswa('Budi', 70, 65, 80),
    // tambahkan 3 lainnya
  ];
  
  // Tampilkan semua
  for (var s in daftar) {
    print(s);
  }
  
  // Rata-rata
  double total = 0;
  for (var s in daftar) {
    total += s.nilaiAkhir;
  }
  print('Rata-rata kelas: ${(total / daftar.length).toStringAsFixed(1)}');
}

🧪 PRAKTIKUM 4 — STATE MANAGEMENT DASAR (setState)


📖 Teori Singkat

Di Flutter, setState() memberi tahu framework bahwa ada data yang berubah, sehingga UI perlu di-rebuild.


🟢 Praktikum 4 — Aplikasi Counter + List Siswa

Kode Dasar (Flutter)

dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Manajemen Siswa')),
        body: SiswaList(),
      ),
    );
  }
}

class SiswaList extends StatefulWidget {
  
  _SiswaListState createState() => _SiswaListState();
}

class _SiswaListState extends State<SiswaList> {
  List<String> siswa = ['Andi', 'Budi', 'Citra'];
  final TextEditingController _controller = TextEditingController();
  
  void _tambahSiswa() {
    if (_controller.text.isNotEmpty) {
      setState(() {
        siswa.add(_controller.text);
        _controller.clear();
      });
    }
  }
  
  void _hapusSiswa(int index) {
    setState(() {
      siswa.removeAt(index);
    });
  }
  
  
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20),
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: TextField(
                  controller: _controller,
                  decoration: InputDecoration(
                    labelText: 'Nama Siswa',
                    border: OutlineInputBorder(),
                  ),
                ),
              ),
              SizedBox(width: 10),
              ElevatedButton(
                onPressed: _tambahSiswa,
                child: Text('Tambah'),
              ),
            ],
          ),
          SizedBox(height: 20),
          Expanded(
            child: ListView.builder(
              itemCount: siswa.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(siswa[index]),
                  trailing: IconButton(
                    icon: Icon(Icons.delete, color: Colors.red),
                    onPressed: () => _hapusSiswa(index),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

✏️ Latihan 4

  1. Modifikasi program di atas sehingga data siswa menggunakan class Siswa (dengan tugas, uts, uas).

  2. Tampilkan nilai akhir di setiap list tile.

  3. Tambahkan tombol "Hitung Semua" yang menampilkan:

    • Rata-rata kelas

    • Siswa dengan nilai tertinggi

    • Jumlah siswa lulus


🧪 PRAKTIKUM 5 — NAVIGASI & ROUTING


📖 Teori Singkat

Navigasi digunakan untuk berpindah halaman.


🟢 Praktikum 5 — Navigasi Dasar

Kode Dasar

dart
// Halaman Pertama
class HomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => DetailPage()),
            );
          },
          child: Text('Ke Detail'),
        ),
      ),
    );
  }
}

// Halaman Kedua
class DetailPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Detail')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Kembali'),
        ),
      ),
    );
  }
}

🟢 Praktikum 5B — Kirim Data Antar Halaman

dart
// Kirim data
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DetailPage(
      nama: 'Andi',
      nilai: 85,
    ),
  ),
);

// Terima data di DetailPage
class DetailPage extends StatelessWidget {
  final String nama;
  final double nilai;
  
  const DetailPage({required this.nama, required this.nilai});
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Detail $nama')),
      body: Center(
        child: Text('Nilai: $nilai'),
      ),
    );
  }
}

✏️ Latihan 5

Buat aplikasi dengan 3 halaman:

  1. Halaman Daftar Siswa (ListView)

  2. Halaman Tambah Siswa (Form)

  3. Halaman Detail Siswa (Tampilkan semua data)

Saat tombol "Tambah" di halaman 2 ditekan, data siswa baru muncul di halaman 1.
Saat item siswa di halaman 1 ditekan, pindah ke halaman 3.


🧪 PRAKTIKUM 6 — SHAREDPREFERENCES (Local Storage)


📖 Teori Singkat

SharedPreferences digunakan untuk menyimpan data sederhana (key-value) secara permanen di perangkat.


🟢 Praktikum 6 — Simpan & Baca Data

Langkah 1: Tambahkan dependency di pubspec.yaml

yaml
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

Langkah 2: Kode Dasar

dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SimpanDataPage(),
    );
  }
}

class SimpanDataPage extends StatefulWidget {
  
  _SimpanDataPageState createState() => _SimpanDataPageState();
}

class _SimpanDataPageState extends State<SimpanDataPage> {
  String _nama = '';
  final TextEditingController _controller = TextEditingController();

  
  void initState() {
    super.initState();
    _loadData();
  }

  // Fungsi untuk menyimpan data
  Future<void> _saveData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('nama', _controller.text);
    setState(() {
      _nama = _controller.text;
    });
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Data berhasil disimpan!')),
    );
  }

  // Fungsi untuk membaca data
  Future<void> _loadData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _nama = prefs.getString('nama') ?? 'Belum ada data';
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('SharedPreferences')),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Masukkan Nama',
                border: OutlineInputBorder(),
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveData,
              child: Text('Simpan'),
            ),
            SizedBox(height: 20),
            Text(
              'Nama tersimpan: $_nama',
              style: TextStyle(fontSize: 20),
            ),
            ElevatedButton(
              onPressed: _loadData,
              child: Text('Muat Ulang'),
            ),
          ],
        ),
      ),
    );
  }
}

✏️ Latihan 6

  1. Modifikasi aplikasi Penilaian sebelumnya agar data siswa tersimpan di SharedPreferences.

  2. Saat aplikasi dibuka kembali, data tetap ada.

  3. Tambahkan fitur hapus semua data.


🧪 PRAKTIKUM 7 — PROJECT AKHIR: APLIKASI CRUD SISWA


🎯 Deskripsi Project

Buat aplikasi Manajemen Data Siswa dengan fitur:

Fitur Wajib

  • ✅ Tambah data siswa (nama, tugas, uts, uas)

  • ✅ Tampilkan daftar siswa (ListView)

  • ✅ Edit data siswa

  • ✅ Hapus data siswa

  • ✅ Hitung nilai akhir, predikat, status

  • ✅ Simpan data ke SharedPreferences

  • ✅ Navigasi antar halaman

Fitur Tambahan (Nilai Plus)

  • 🔥 Pencarian siswa

  • 🔥 Sorting (nilai tertinggi/terendah)

  • 🔥 Ekspor data ke file

  • 🔥 Grafik nilai


🏗️ Struktur Project

text
lib/
├── main.dart
├── models/
│   └── siswa.dart          # Class Siswa
├── screens/
│   ├── home_screen.dart    # Daftar siswa
│   ├── tambah_screen.dart  # Tambah/edit siswa
│   └── detail_screen.dart  # Detail siswa
└── services/
    └── storage_service.dart # SharedPreferences service

💻 Kode Starter (main.dart)

dart
import 'package:flutter/material.dart';
import 'screens/home_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Manajemen Siswa',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}

✏️ Tugas Siswa

Kerjakan langkah-langkah berikut:

📝 Langkah 1: Buat Class Siswa

Buat file lib/models/siswa.dart dengan class Siswa lengkap (property, constructor, method nilaiAkhir, predikat, status).

📝 Langkah 2: Buat Storage Service

Buat file lib/services/storage_service.dart dengan fungsi:

  • Future<List<Siswa>> loadSiswa()

  • Future<void> saveSiswa(List<Siswa> daftar)

📝 Langkah 3: Buat HomeScreen

Tampilkan daftar siswa dalam ListView.builder.
Setiap item punya tombol:

  • Edit → navigasi ke halaman tambah dengan data

  • Hapus → hapus siswa dengan konfirmasi

📝 Langkah 4: Buat TambahScreen

Form dengan 4 TextField (nama, tugas, uts, uas).
Tombol simpan untuk:

  • Tambah baru (jika tidak ada data)

  • Update data (jika ada data yang diedit)

📝 Langkah 5: Buat DetailScreen

Tampilkan semua data siswa dalam Card, lengkap dengan:

  • Nama

  • Tugas, UTS, UAS

  • Nilai Akhir (dengan 1 desimal)

  • Predikat (A-E)

  • Status (LULUS/TIDAK LULUS) dengan warna berbeda


🧩 Contoh UI

text
┌─────────────────────────────────┐
│   📚 Manajemen Data Siswa       │
├─────────────────────────────────┤
│  [🔍 Cari siswa...]             │
│                                  │
│  ➕ TAMBAH SISWA                 │
│                                  │
│  ┌───────────────────────────┐  │
│  │ Andi          [✏️] [🗑️] │  │
│  │ NA: 82.5  Predikat: B    │  │
│  │ Status: ✅ LULUS          │  │
│  ├───────────────────────────┤  │
│  │ Budi          [✏️] [🗑️] │  │
│  │ NA: 55.0  Predikat: E    │  │
│  │ Status: ❌ TIDAK LULUS   │  │
│  └───────────────────────────┘  │
│                                  │
│  📊 Statistik:                   │
│  Rata-rata: 75.2                │
│  Tertinggi: Andi (90.0)         │
│  Terendah: Budi (55.0)          │
│  Lulus: 3 dari 5 siswa          │
└─────────────────────────────────┘

📋 LKPD / RUBRIK PENILAIAN PROJECT

NoKomponenBobotNilai
1Class Siswa (OOP)15
2CRUD (Tambah, Tampil, Edit, Hapus)25
3SharedPreferences (Penyimpanan)15
4Navigasi10
5UI/UX (Material Design)15
6Validasi Input10
7Fitur Tambahan (Pencarian/Sorting/Statistik)10
Total100

💡 Tips Pembelajaran

  1. Minta ke Guru template starter untuk siswa yang masih kesulitan.

  2. Jika masih kesulitan minta secara bertahap (Tambah → Tampil → Hapus → Edit).

  3. Pair programming untuk siswa yang lebih cepat dengan yang lambat.

  4. Demo project di akhir supaya terbiasa presentasi.


🎉 SELESAI!

Dengan menyelesaikan modul ini, siswa telah:
✅ Menguasai koleksi data (List, Map, Set)
✅ Membuat fungsi sendiri
✅ Membuat Class & Object
✅ Mengelola state dengan setState
✅ Membuat navigasi antar halaman
✅ Menyimpan data dengan SharedPreferences
✅ Membuat aplikasi CRUD lengkap

Selamat, kalian sudah siap membuat aplikasi Flutter yang nyata! 🚀


Share:

Tidak ada komentar:

Posting Komentar

Categories

Blogger Tricks

Blogger Themes