从零开始:用 Flutter 构建一个简洁高效的待办事项应用V1.0.0

用 Flutter 构建一个简洁高效的待办事项应用V1.0.0

  • [📋 前言](#📋 前言)
    • [🎯 为什么选择待办事项作为入门项目?](#🎯 为什么选择待办事项作为入门项目?)
    • [🏗️ 一、项目结构设计:清晰胜于聪明](#🏗️ 一、项目结构设计:清晰胜于聪明)
    • [🧱 二、数据模型:定义"任务"的本质](#🧱 二、数据模型:定义“任务”的本质)
    • [🖼️ 三、UI 组件拆解:从整体到局部](#🖼️ 三、UI 组件拆解:从整体到局部)
      • [1. 主页面:`HomeScreen`](#1. 主页面:HomeScreen)
      • [2. 列表组件:`TodoList`](#2. 列表组件:TodoList)
      • [3. 单项组件:`TodoItem`](#3. 单项组件:TodoItem)
    • [➕ 四、添加新任务:对话框交互](#➕ 四、添加新任务:对话框交互)
    • [🎨 五、运行效果预览](#🎨 五、运行效果预览)
    • [🔜 六、下一步优化方向](#🔜 六、下一步优化方向)
    • [💡 结语:小应用,大收获](#💡 结语:小应用,大收获)

📋 前言

"完成一件事,就划掉一项"------这是待办清单最朴素的魅力。

而用 Flutter 实现它,不仅能让你掌握跨平台开发的核心技能,还能亲手打造一个真正可用的工具。

本文将带你一步步构建一个结构清晰、可扩展的 Flutter To-Do 应用,涵盖项目架构设计、状态管理、组件拆分等关键概念,助你迈出 Flutter 实战的第一步。


🎯 为什么选择待办事项作为入门项目?

待办应用虽小,却五脏俱全:

  • ✅ 列表渲染(ListView.builder)
  • ✅ 用户交互(添加、勾选)
  • ✅ 状态管理(任务完成状态)
  • ✅ 对话框输入(AlertDialog + TextField)
  • ✅ 组件化思维(分离 UI 与逻辑)

它是学习 Flutter 的"黄金练习题"。


🏗️ 一、项目结构设计:清晰胜于聪明

良好的目录结构是可维护性的基石。我们采用经典的分层模式:

复制代码
lib/
├── main.dart              # 应用入口
├── models/                # 数据模型
│   └── todo.dart
├── screens/               # 页面级组件
│   └── home_screen.dart
└── widgets/               # 可复用 UI 组件
    ├── todo_list.dart
    └── todo_item.dart

💡 原则:

  • models:纯数据,无 UI
  • screens:页面容器,持有状态
  • widgets:无状态或受控组件,专注渲染

这种结构让代码易于阅读、测试和扩展。


🧱 二、数据模型:定义"任务"的本质

在 lib/models/todo.dart 中,我们定义了最核心的数据结构:

dart 复制代码
class Todo {
  String title;
  bool isDone;

  Todo({required this.title, this.isDone = false});
}
  • title:任务内容(字符串)
  • isDone:完成状态(布尔值,默认未完成)

🔑 注意:这里使用 可变字段(非 final),是为了在简单示例中直接修改状态。在大型项目中,建议使用不可变对象 + 状态管理库(如 Provider)。


🖼️ 三、UI 组件拆解:从整体到局部

1. 主页面:HomeScreen

HomeScreen 是整个应用的"大脑":

  • 持有 _todos 列表(状态)
  • 提供 _addTodo 和 _toggleTodoStatus 方法(状态变更)
  • 渲染 TodoList 并传递回调函数
dart 复制代码
class _HomeScreenState extends State<HomeScreen> {
  final List<Todo> _todos = [...];

  void _addTodo(String title) { ... }
  void _toggleTodoStatus(int index) { ... }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TodoList(todos: _todos, toggleStatus: _toggleTodoStatus),
      floatingActionButton: FloatingActionButton(onPressed: _addTodoDialog),
    );
  }
}

✅ 这体现了 StatefulWidget 的典型用法:状态在 State 类中管理,UI 响应状态变化。


2. 列表组件:TodoList

TodoList 是一个 无状态组件(StatelessWidget),只负责渲染:

dart 复制代码
class TodoList extends StatelessWidget {
  final List<Todo> todos;
  final Function(int) toggleStatus;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: todos.length,
      itemBuilder: (context, index) {
        return TodoItem(
          todo: todos[index],
          toggleStatus: () => toggleStatus(index),
        );
      },
    );
  }
}
  • 接收 todos 列表和 toggleStatus 回调
  • 使用 ListView.builder 高效渲染长列表

3. 单项组件:TodoItem

每个任务项的 UI 封装在 TodoItem 中:

dart 复制代码
class TodoItem extends StatelessWidget {
  final Todo todo;
  final Function toggleStatus;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(todo.title,
        style: TextStyle(
          decoration: todo.isDone ? TextDecoration.lineThrough : TextDecoration.none,
        )),
      trailing: Checkbox(
        value: todo.isDone,
        onChanged: (value) => toggleStatus(),
      ),
    );
  }
}
  • 根据 isDone 决定是否显示删除线
  • 点击复选框触发父组件的状态更新

🔄 数据流 :
TodoItem → 调用 toggleStatus() → HomeScreen 修改 _todos[index].isDone → Flutter 自动重建 UI


➕ 四、添加新任务:对话框交互

通过 FloatingActionButton 触发添加流程:

dart 复制代码
void _addTodoDialog() {
  final controller = TextEditingController();
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      content: TextField(controller: controller),
      actions: [
        TextButton(onPressed: () { Navigator.pop(context); }, child: Text('取消')),
        TextButton(onPressed: () {
          Navigator.pop(context);
          _addTodo(controller.text);
        }, child: Text('添加')),
      ],
    ),
  );
}
  • 使用 TextEditingController 获取输入内容
  • 对话框关闭后才添加任务,避免空值

🎨 五、运行效果预览

启动应用后,你将看到:

  • AppBar 标题:"代办事项"
  • 初始两条示例任务
  • 每条任务左侧为标题,右侧为复选框
  • 已完成任务自动添加删除线
  • 点击右下角 "+" 按钮可添加新任务

---

🔜 六、下一步优化方向

当前版本功能完整但基础,你可以尝试以下增强:

功能 实现建议
数据持久化 使用 shared_preferences 或 hive 保存任务
删除任务 长按或滑动删除(Dismissible)
编辑任务 点击任务进入编辑页
分类/标签 添加 category 字段
搜索/过滤 按"全部/未完成/已完成"筛选
主题切换 支持深色模式

例如,添加删除功能只需在 TodoItem 中包裹 Dismissible:

dart 复制代码
Dismissible(
  key: Key(todo.title),
  onDismissed: (direction) {
    // 调用删除回调
  },
  child: TodoItem(...),
)

💡 结语:小应用,大收获

这个待办事项应用虽然只有几十行核心代码,却涵盖了 Flutter 开发的核心范式:

  • 声明式 UI
  • 组件化拆分
  • 状态向下传递,事件向上冒泡
  • 响应式更新

🌟 记住:所有复杂应用,都是从一个简单的列表开始的。

现在,打开你的 IDE,运行 flutter create todo_app,把这份代码变成你自己的第一个作品吧!

相关推荐
橙橙笔记3 小时前
QT的学习第四部分
linux·qt·学习·音视频
恋猫de小郭3 小时前
Flutter 下 AOT 一个你怎么都想不出来的 Bug ,JIT 正常的计算,在 AOT 居然算错了
android·前端·flutter
叼烟扛炮3 小时前
Linux 学习笔记(五十四):内网穿透实战——用 frp 让外网访问你的私人电脑
linux·服务器·网络·笔记·学习
在猴站学算法3 小时前
(《统计学习方法》(第2版) 李航)第2章 感知机算法
学习·算法·机器学习·统计学习
旖旎夜光4 小时前
【C++ 基础入门】C++ 继承(上):概念、切片、隐藏、默认成员函数与友元
c++·笔记·学习
Godspeed Zhao4 小时前
从零开始学AI24——无监督学习之K均值
学习·机器学习
叼烟扛炮4 小时前
[LangChain] 学习笔记(05):提示词模板(Prompt)与少样本注入(Few-Shot)实战
linux·人工智能·笔记·学习·langchain·prompt
La Pulga17 小时前
【FreeRTOS源码学习笔记】任务延时列表
笔记·mcu·学习·嵌入式·freertos·实时操作系统
2035去旅行17 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
楚山之石18 小时前
【JCO】mpMRI 先行替代 TURBT 初始分期:BladderPath 随机试验让 MIBC 患者提前 45 天得到正确治疗
人工智能·学习·mri·医学影像