返回

Flutter:构建动态的 todo list 应用

IOS

Flutter:构建动态的 todo list 应用

Flutter 是一款用于构建跨平台移动应用的开源 UI 框架,由 Google 开发。它允许您使用一套代码库为 iOS、Android、Web 和桌面平台构建应用。Flutter 的优势在于它具有出色的性能、灵活的 UI 设计和丰富的组件库。

在本教程中,我们将使用 Flutter 构建一个动态的 todo list 应用。这个应用将允许您创建、编辑和删除任务,并使用内置的 SQLite 数据库来持久化数据。

先决条件

在开始之前,您需要确保已经满足以下先决条件:

  • 已安装 Flutter SDK。
  • 已安装 Android Studio 或 Visual Studio Code。
  • 已创建一个 Flutter 项目。

创建项目

  1. 打开您喜欢的 IDE 并创建一个新的 Flutter 项目。
  2. 将项目命名为 "todo_list"。
  3. 等待 Flutter 创建项目。

创建数据库

我们首先需要创建一个 SQLite 数据库来存储我们的任务数据。

  1. 在 "lib" 目录下创建一个名为 "database.dart" 的文件。
  2. 在该文件中添加以下代码:
import 'package:sqflite/sqflite.dart';

class DatabaseHelper {
  static final _databaseName = "todo_list.db";
  static final _databaseVersion = 1;

  static Database? _database;

  Future<Database> get database async {
    if (_database != null) return _database!;

    _database = await openDatabase(_databaseName, version: _databaseVersion,
        onCreate: (db, version) {
      db.execute(
          "CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT, description TEXT, completed INTEGER)");
    });
    return _database!;
  }

  Future<int> insertTask(Task task) async {
    final db = await database;
    return await db.insert('tasks', task.toMap());
  }

  Future<List<Task>> getTasks() async {
    final db = await database;
    final List<Map<String, dynamic>> maps = await db.query('tasks');
    return List.generate(maps.length, (i) => Task.fromMap(maps[i]));
  }

  Future<int> updateTask(Task task) async {
    final db = await database;
    return await db.update('tasks', task.toMap(),
        where: 'id = ?', whereArgs: [task.id]);
  }

  Future<int> deleteTask(int id) async {
    final db = await database;
    return await db.delete('tasks', where: 'id = ?', whereArgs: [id]);
  }
}

class Task {
  final int id;
  final String title;
  final String description;
  final int completed;

  Task({this.id, required this.title, required this.description, this.completed = 0});

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'completed': completed,
    };
  }

  static Task fromMap(Map<String, dynamic> map) {
    return Task(
      id: map['id'],
      title: map['title'],
      description: map['description'],
      completed: map['completed'],
    );
  }
}

创建 UI

现在我们需要创建我们的应用的 UI。

  1. 在 "lib" 目录下创建一个名为 "home_page.dart" 的文件。
  2. 在该文件中添加以下代码:
import 'package:flutter/material.dart';
import 'package:todo_list/database.dart';
import 'package:todo_list/task.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final DatabaseHelper _databaseHelper = DatabaseHelper();
  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _descriptionController = TextEditingController();
  final List<Task> _tasks = [];

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

  Future<void> _getTasks() async {
    final tasks = await _databaseHelper.getTasks();
    setState(() {
      _tasks.addAll(tasks);
    });
  }

  Future<void> _addTask() async {
    final task = Task(title: _titleController.text, description: _descriptionController.text);
    await _databaseHelper.insertTask(task);
    setState(() {
      _tasks.add(task);
    });
  }

  Future<void> _updateTask(Task task) async {
    await _databaseHelper.updateTask(task);
    setState(() {
      _tasks[_tasks.indexWhere((t) => t.id == task.id)] = task;
    });
  }

  Future<void> _deleteTask(int id) async {
    await _databaseHelper.deleteTask(id);
    setState(() {
      _tasks.removeWhere((t) => t.id == id);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todo List'),
      ),
      body: ListView.builder(
        itemCount: _tasks.length,
        itemBuilder: (context, index) {
          final task = _tasks[index];
          return ListTile(
            title: Text(task.title),
            subtitle: Text(task.description),
            trailing: Checkbox(
              value: task.completed == 1,
              onChanged: (value) {
                task.completed = value! ? 1 : 0;
                _updateTask(task);
              },
            ),
            onLongPress: () => _deleteTask(task.id),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (context) {
              return AlertDialog(
                title: const Text('Add Task'),
                content: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      controller: _titleController,
                      decoration: const InputDecoration(hintText: 'Title'),
                    ),
                    TextField(
                      controller: _descriptionController,
                      decoration: const InputDecoration(hintText: 'Description'),
                    ),
                  ],
                ),
                actions: [
                  TextButton(
                    onPressed: () {
                      Navigator.pop(context);
                    },
                    child: const Text('Cancel'),
                  ),
                  TextButton(
                    onPressed: () {
                      _addTask();
                      Navigator.pop(context);
                    },
                    child: const Text('Add'),
                  ),
                ],
              );
            },
          );
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

运行应用

现在我们可以运行我们的应用了。

  1. 在终端中进入您的项目目录。
  2. 运行 "flutter run" 命令。

您的应用现在应该在模拟器或真机上运行了。

结语

在本教程中,我们学习了如何使用 Flutter 构建一个动态的 todo list 应用。我们创建了一个 SQLite 数据库来存储任务数据,并创建了一个 UI 来显示和管理任务。我们还学习了如何使用 Flutter 的状态管理系统来更新 UI。