Kamis, 24 April 2025

aplikasi To-Do List dengan fitur CRUD menggunakan SQLite

 Berikut adalah contoh kode Flutter lengkap untuk aplikasi To-Do List dengan fitur CRUD menggunakan SQLite:


---


### **1. Tambahkan dependensi di `pubspec.yaml`:**


```yaml

dependencies:

  flutter:

    sdk: flutter

  sqflite: ^2.3.0

  path: ^1.9.0

```


---


### **2. Buat file model: `models/todo.dart`**


```dart

class Todo {

  int? id;

  String title;

  String description;


  Todo({this.id, required this.title, required this.description});


  Map<String, dynamic> toMap() {

    return {

      'id': id,

      'title': title,

      'description': description,

    };

  }


  factory Todo.fromMap(Map<String, dynamic> map) {

    return Todo(

      id: map['id'],

      title: map['title'],

      description: map['description'],

    );

  }

}

```


---


### **3. Buat file database helper: `helpers/database_helper.dart`**


```dart

import 'package:sqflite/sqflite.dart';

import 'package:path/path.dart';

import '../models/todo.dart';


class DatabaseHelper {

  static final DatabaseHelper _instance = DatabaseHelper._internal();

  factory DatabaseHelper() => _instance;

  DatabaseHelper._internal();


  static Database? _database;


  Future<Database> get database async {

    return _database ??= await _initDatabase();

  }


  Future<Database> _initDatabase() async {

    final dbPath = await getDatabasesPath();

    final path = join(dbPath, 'todo.db');


    return openDatabase(

      path,

      version: 1,

      onCreate: (db, version) async {

        await db.execute('''

          CREATE TABLE todos (

            id INTEGER PRIMARY KEY AUTOINCREMENT,

            title TEXT,

            description TEXT

          )

        ''');

      },

    );

  }


  Future<int> insertTodo(Todo todo) async {

    final db = await database;

    return await db.insert('todos', todo.toMap());

  }


  Future<List<Todo>> getTodos() async {

    final db = await database;

    final maps = await db.query('todos');

    return List.generate(maps.length, (i) {

      return Todo.fromMap(maps[i]);

    });

  }


  Future<int> updateTodo(Todo todo) async {

    final db = await database;

    return await db.update(

      'todos',

      todo.toMap(),

      where: 'id = ?',

      whereArgs: [todo.id],

    );

  }


  Future<int> deleteTodo(int id) async {

    final db = await database;

    return await db.delete('todos', where: 'id = ?', whereArgs: [id]);

  }

}

```


---


### **4. Buat file utama: `main.dart`**


```dart

import 'package:flutter/material.dart';

import 'helpers/database_helper.dart';

import 'models/todo.dart';


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


class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      title: 'To-Do List CRUD',

      theme: ThemeData(primarySwatch: Colors.blue),

      home: TodoListScreen(),

    );

  }

}


class TodoListScreen extends StatefulWidget {

  @override

  _TodoListScreenState createState() => _TodoListScreenState();

}


class _TodoListScreenState extends State<TodoListScreen> {

  final dbHelper = DatabaseHelper();

  List<Todo> todos = [];


  @override

  void initState() {

    super.initState();

    refreshTodos();

  }


  void refreshTodos() async {

    final data = await dbHelper.getTodos();

    setState(() {

      todos = data;

    });

  }


  void showTodoDialog({Todo? todo}) {

    final titleController = TextEditingController(text: todo?.title);

    final descController = TextEditingController(text: todo?.description);


    showDialog(

      context: context,

      builder: (_) => AlertDialog(

        title: Text(todo == null ? 'Tambah Todo' : 'Edit Todo'),

        content: Column(

          mainAxisSize: MainAxisSize.min,

          children: [

            TextField(controller: titleController, decoration: InputDecoration(labelText: 'Judul')),

            TextField(controller: descController, decoration: InputDecoration(labelText: 'Deskripsi')),

          ],

        ),

        actions: [

          TextButton(onPressed: () => Navigator.pop(context), child: Text('Batal')),

          ElevatedButton(

            onPressed: () async {

              final title = titleController.text;

              final desc = descController.text;

              if (title.isNotEmpty && desc.isNotEmpty) {

                if (todo == null) {

                  await dbHelper.insertTodo(Todo(title: title, description: desc));

                } else {

                  await dbHelper.updateTodo(Todo(id: todo.id, title: title, description: desc));

                }

                refreshTodos();

                Navigator.pop(context);

              }

            },

            child: Text('Simpan'),

          ),

        ],

      ),

    );

  }


  void deleteTodo(int id) async {

    await dbHelper.deleteTodo(id);

    refreshTodos();

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(title: Text('To-Do List')),

      body: ListView.builder(

        itemCount: todos.length,

        itemBuilder: (context, index) {

          final todo = todos[index];

          return ListTile(

            title: Text(todo.title),

            subtitle: Text(todo.description),

            trailing: Row(

              mainAxisSize: MainAxisSize.min,

              children: [

                IconButton(icon: Icon(Icons.edit), onPressed: () => showTodoDialog(todo: todo)),

                IconButton(icon: Icon(Icons.delete), onPressed: () => deleteTodo(todo.id!)),

              ],

            ),

          );

        },

      ),

      floatingActionButton: FloatingActionButton(

        child: Icon(Icons.add),

        onPressed: () => showTodoDialog(),

      ),

    );

  }

}

```


---


Kalau kamu mau aku bantu buatkan folder strukturnya atau ingin menambahkan fitur lain seperti pencarian, kategori, atau deadline, tinggal bilang aja!

Tidak ada komentar:

Posting Komentar

WARUNG GORENGAN - SENDI

🍽️ Warung Gorengan Aplikasi Jastip Gorengan Kantin - Solusi Modern untuk Pesan...