flutter project to do app | java php laravel linux mysql sql bootstrap html css query java php laravel linux mysql sql bootstrap html css query: flutter project to do app

Monday, May 4, 2026

flutter project to do app

🚀 PROJECT: TO-DO APP 📱 FLUTTER 🎯 ARTIKEL 15 / 16

Project Akhir Bagian 1
Bangun Aplikasi
To-Do List Lengkap

Saatnya semua ilmu Dart & Flutter yang kamu pelajari dalam seri ini diwujudkan jadi sebuah aplikasi nyata. Siap meluncur? 🛸

⏱️
Estimasi Baca
12–15 Menit
🏆
Level
Project Akhir
📅
Tahun
2026
📦
Seri
Dart From Zero to Zorro

Pernah nggak kamu buka aplikasi to-do list di HP, terus tiba-tiba kepikiran: "Gimana ya cara bikinnya?" Nah, artikel ini adalah jawabannya — dan lebih dari itu. Kalau kamu sudah mengikuti seri Dart From Zero to Zorro dari artikel pertama, kamu sudah punya semua bahan untuk membangun sebuah project Flutter to-do list Android yang fungsional dan siap digunakan. Ini bukan latihan kecil-kecilan. Ini adalah proyek nyata yang akan kamu banggakan.

Di Bagian 1 ini, kita akan menyiapkan fondasi proyek: struktur folder, model data, manajemen state, dan UI utama aplikasi. Anggap ini seperti membangun fondasi rumah — kalau fondasinya kokoh, bangunan di atasnya pasti kuat. 🏗️

📐 Definisi Project

Project Flutter To-Do List Android adalah aplikasi mobile yang memungkinkan pengguna menambah, menandai selesai, dan menghapus tugas — dengan data yang tersimpan secara lokal di perangkat. Proyek ini menggabungkan: State Management, Local Storage, Widget Tree, dan Clean Architecture — semua yang sudah kamu pelajari dalam seri ini.

🎯 Kenapa Project Flutter To-Do List Android Adalah Proyek Terbaik untuk Pemula?

Bayangkan kamu baru belajar masak. Guru terbaik tidak akan langsung menyuruhmu bikin rendang 8 jam. Mereka minta kamu goreng telur dulu — sederhana, tapi mengajarkan semua teknik dasar: panas api, timing, dan rasa.

To-Do List adalah "goreng telur"-nya dunia Flutter. Sederhana di permukaan, tapi di baliknya tersembunyi hampir semua konsep penting yang perlu kamu kuasai sebagai Flutter developer.

Konsep Flutter Dipakai di To-Do App? Di Mana?
StatefulWidget ✅ Ya Tambah / hapus tugas
ListView.builder ✅ Ya Menampilkan daftar tugas
SharedPreferences / Hive ✅ Ya Simpan data lokal
Model Class (OOP) ✅ Ya Struktur data Task
setState() & Rebuild ✅ Ya Update UI saat tugas berubah
🔥
Fakta Menarik

Hampir 90% tutorial Flutter untuk pemula menggunakan To-Do List sebagai proyek pertama. Bukan kebetulan — aplikasi ini memaksa kamu memahami siklus hidup data dari input pengguna → state → penyimpanan → tampilan. Itu adalah alur kerja semua aplikasi mobile modern.

🛠️ Step-by-Step: Membangun Project Flutter To-Do List Android dari Nol

Ikuti setiap langkah berikut dengan seksama. Kita mulai dari membuat project baru hingga UI yang siap dijalankan di Android.

1

Buat Project Flutter Baru

Buka terminal, arahkan ke folder kerjamu, dan jalankan perintah berikut. Nama project pakai huruf kecil dan underscore.

Terminal
flutter create todo_app_dart
cd todo_app_dart
flutter run
2

Tambahkan Dependency di pubspec.yaml

Kita pakai shared_preferences untuk menyimpan data lokal dan uuid untuk membuat ID unik setiap tugas.

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.3
  uuid: ^4.3.3
💡
Tips

Setelah mengubah pubspec.yaml, selalu jalankan flutter pub get di terminal agar dependency ter-download otomatis. Lupa langkah ini adalah penyebab error #1 pemula.

3

Buat Model Class: task.dart

Buat file baru di lib/models/task.dart. Model ini adalah blueprint data setiap tugas — seperti KTP untuk setiap item di daftar kamu.

lib/models/task.dart
class Task {
  final String id;
  String title;
  bool isDone;
  DateTime createdAt;

  Task({
    required this.id,
    required this.title,
    this.isDone = false,
    DateTime? createdAt,
  }) : createdAt = createdAt ?? DateTime.now();

  // Konversi ke Map untuk disimpan di SharedPreferences
  Map<String, dynamic> toMap() => {
    'id': id,
    'title': title,
    'isDone': isDone,
    'createdAt': createdAt.toIso8601String(),
  };

  // Buat Task dari Map saat membaca data
  factory Task.fromMap(Map<String, dynamic> map) => Task(
    id: map['id'],
    title: map['title'],
    isDone: map['isDone'],
    createdAt: DateTime.parse(map['createdAt']),
  );
}
4

Buat Service Penyimpanan: task_service.dart

File ini bertanggung jawab menyimpan dan membaca data dari SharedPreferences. Buat di lib/services/task_service.dart.

lib/services/task_service.dart
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/task.dart';

class TaskService {
  static const String _key = 'tasks_data';

  Future<List<Task>> loadTasks() async {
    final prefs = await SharedPreferences.getInstance();
    final data = prefs.getString(_key);
    if (data == null) return [];
    final List decoded = jsonDecode(data);
    return decoded.map((e) => Task.fromMap(e)).toList();
  }

  Future<void> saveTasks(List<Task> tasks) async {
    final prefs = await SharedPreferences.getInstance();
    final data = jsonEncode(tasks.map((t) => t.toMap()).toList());
    await prefs.setString(_key, data);
  }
}
5

Bangun UI Utama: home_screen.dart

Ini adalah layar utama aplikasi. Di sini semua state dikelola dan UI ditampilkan. Buat di lib/screens/home_screen.dart.

lib/screens/home_screen.dart
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../models/task.dart';
import '../services/task_service.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final TaskService _service = TaskService();
  final TextEditingController _ctrl = TextEditingController();
  final Uuid _uuid = const Uuid();
  List<Task> _tasks = [];

  @override
  void initState() {
    super.initState();
    _loadTasks();
  }

  Future<void> _loadTasks() async {
    final data = await _service.loadTasks();
    setState(() => _tasks = data);
  }

  Future<void> _addTask() async {
    if (_ctrl.text.trim().isEmpty) return;
    final newTask = Task(
      id: _uuid.v4(),
      title: _ctrl.text.trim(),
    );
    setState(() => _tasks.add(newTask));
    _ctrl.clear();
    await _service.saveTasks(_tasks);
  }

  Future<void> _toggleTask(int index) async {
    setState(() => _tasks[index].isDone = !_tasks[index].isDone);
    await _service.saveTasks(_tasks);
  }

  Future<void> _deleteTask(int index) async {
    setState(() => _tasks.removeAt(index));
    await _service.saveTasks(_tasks);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('📋 My To-Do List'),
        backgroundColor: const Color(0xFF6366F1),
        foregroundColor: Colors.white,
      ),
      body: Column(children: [
        // Input Area
        Padding(
          padding: const EdgeInsets.all(16),
          child: Row(children: [
            Expanded(
              child: TextField(
                controller: _ctrl,
                decoration: const InputDecoration(
                  hintText: 'Tambah tugas baru...',
                  border: OutlineInputBorder(),
                ),
                onSubmitted: (_) => _addTask(),
              ),
            ),
            const SizedBox(width: 8),
            ElevatedButton(
              onPressed: _addTask,
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFF6366F1),
                foregroundColor: Colors.white,
              ),
              child: const Text('Tambah'),
            ),
          ]),
        ),
        // Task List
        Expanded(
          child: ListView.builder(
            itemCount: _tasks.length,
            itemBuilder: (ctx, i) => ListTile(
              leading: Checkbox(
                value: _tasks[i].isDone,
                onChanged: (_) => _toggleTask(i),
                activeColor: const Color(0xFF6366F1),
              ),
              title: Text(
                _tasks[i].title,
                style: TextStyle(
                  decoration: _tasks[i].isDone
                    ? TextDecoration.lineThrough
                    : null,
                  color: _tasks[i].isDone
                    ? Colors.grey
                    : Colors.black87,
                ),
              ),
              trailing: IconButton(
                icon: const Icon(Icons.delete_outline,
                  color: Colors.redAccent),
                onPressed: () => _deleteTask(i),
              ),
            ),
          ),
        ),
      ]),
    );
  }
}
Insight Penting

Perhatikan pola setState() → simpan ke storage → rebuild UI. Inilah siklus state management paling fundamental di Flutter. Memahami pola ini di sini akan membuat kamu jauh lebih mudah memahami Provider, Riverpod, atau BLoC di masa depan.

🏛️ Analisis Arsitektur Project Flutter To-Do List Android Ini

Kenapa kita tidak menaruh semua kode di satu file saja? Jawabannya: skalabilitas dan keterbacaan. Struktur folder yang rapi adalah tanda seorang developer profesional.

🗂️ Struktur Folder Project
lib/
├── models/
│   └── task.dart         # Blueprint data Task
├── services/
│   └── task_service.dart  # Logic simpan & baca data
├── screens/
│   └── home_screen.dart   # UI + State management
└── main.dart            # Entry point aplikasi
📁 models/

Definisi struktur data. Tidak ada logic bisnis di sini — murni blueprint.

⚙️ services/

Semua interaksi dengan storage/API. Terpisah dari UI agar mudah diganti.

📱 screens/

Widget dan UI. Hanya memanggil service, tidak langsung sentuh storage.

🚀 main.dart

Entry point minimal. Hanya menjalankan app dan routing halaman pertama.

⚠️
Perhatian

Jangan lupa update lib/main.dart untuk mengarahkan ke HomeScreen yang baru dibuat. Tanpa ini, aplikasi akan tetap menampilkan template default Flutter yang membingungkan.

6

Update Entry Point: main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'To-Do App',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorSchemeSeed: const Color(0xFF6366F1),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}
Insight: useMaterial3

useMaterial3: true mengaktifkan sistem desain Material 3 terbaru dari Google. Secara otomatis, komponen seperti tombol, chip, dan card akan tampil lebih modern tanpa kode tambahan. Gratis upgrade visual hanya dengan satu baris! ✨

🎉

Kesimpulan: Fondasi Project Sudah Siap!

Di artikel ke-15 ini, kamu telah berhasil membangun fondasi dari sebuah project Flutter to-do list Android yang sesungguhnya. Ini bukan sekadar latihan — ini adalah bukti nyata bahwa kamu sudah menguasai:

✅ Model Class Dart
✅ Local Storage (SharedPreferences)
✅ StatefulWidget & setState()
✅ Arsitektur Folder yang Rapi

Di Artikel 16 — Bagian 2, kita akan menyelesaikan proyek ini sepenuhnya: menambahkan fitur filter tugas, polish UI, lalu build dan deploy ke APK Android yang siap kamu install di HP sendiri. Nantikan! 🚀

💬 Sudah coba build project-nya? Share pengalamanmu di komentar!

Ketemu error? Bingung di bagian mana? Atau berhasil dan mau flexing? Semua boleh! Komentar kamu membantu teman-teman belajar yang lain. 🙌

Tags

#BelajarDart #DartFromZeroToZorro #FlutterProject #ToDoApp #AndroidDev #SharedPreferences #StatefulWidget #ProjectAkhir
📚 Bagian dari Seri

Dart From Zero to Zorro

Artikel ini adalah bagian dari seri lengkap 16 artikel belajar Dart & Flutter dari nol hingga bisa build APK Android. Lihat semua artikel dan ikuti perjalanannya dari awal!

🗺️ Lihat Daftar Isi Lengkap Seri →

No comments:

Post a Comment

saifiahmada.com adalah blog belajar programming Indonesia, membahas lengkap materi bahasa pemrograman: code HTML, CSS, Bootstrap, Desain, PHP, MySQL, coding Java, Query, SQL, dan dunia linux