You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter待办应用开发:如何实现带按钮的列表项管理组件?

实现带操作按钮的Todo列表项组件

作为Flutter新手,你可以通过自定义列表项组件+状态管理的方式实现需求,下面是具体步骤和代码示例:

1. 先定义Todo数据模型

先简单封装待办项的数据结构:

class Todo {
  final String id;
  String title;
  bool isCompleted;

  Todo({required this.id, required this.title, this.isCompleted = false});
}

2. 自定义带操作按钮的列表项组件

把每个待办项的内容、完成状态复选框、编辑/删除按钮封装成独立组件:

class TodoItem extends StatelessWidget {
  final Todo todo;
  final Function(Todo) onEdit;
  final Function(String) onDelete;
  final Function(Todo) onToggleComplete;

  const TodoItem({
    super.key,
    required this.todo,
    required this.onEdit,
    required this.onDelete,
    required this.onToggleComplete,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(8),
        boxShadow: const [
          BoxShadow(color: Colors.black12, blurRadius: 4, offset: Offset(0, 2))
        ],
      ),
      child: Row(
        children: [
          // 完成状态复选框
          Checkbox(
            value: todo.isCompleted,
            onChanged: (value) {
              if (value != null) {
                onToggleComplete(Todo(
                  id: todo.id,
                  title: todo.title,
                  isCompleted: value,
                ));
              }
            },
          ),
          // Todo标题
          Expanded(
            child: Text(
              todo.title,
              style: TextStyle(
                fontSize: 16,
                decoration: todo.isCompleted ? TextDecoration.lineThrough : null,
              ),
            ),
          ),
          // 编辑按钮
          IconButton(
            icon: const Icon(Icons.edit, color: Colors.blue),
            onPressed: () => onEdit(todo),
          ),
          // 删除按钮
          IconButton(
            icon: const Icon(Icons.delete, color: Colors.red),
            onPressed: () => onDelete(todo.id),
          ),
        ],
      ),
    );
  }
}

3. 在主页面集成ListView和AlertDialog

在主页面维护Todo列表的状态,渲染ListView的同时,用你熟悉的AlertDialog处理编辑、删除交互:

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

  @override
  State<TodoPage> createState() => _TodoPageState();
}

class _TodoPageState extends State<TodoPage> {
  final List<Todo> _todos = [
    Todo(id: '1', title: '学习Flutter组件'),
    Todo(id: '2', title: '完成Todo应用'),
  ];
  final TextEditingController _editController = TextEditingController();

  // 编辑Todo的弹窗逻辑
  void _handleEditTodo(Todo todo) {
    _editController.text = todo.title;
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('编辑待办'),
        content: TextField(
          controller: _editController,
          decoration: const InputDecoration(hintText: '输入新的待办内容'),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () {
              if (_editController.text.isNotEmpty) {
                setState(() {
                  final index = _todos.indexWhere((t) => t.id == todo.id);
                  if (index != -1) {
                    _todos[index] = Todo(
                      id: todo.id,
                      title: _editController.text,
                      isCompleted: todo.isCompleted,
                    );
                  }
                });
                Navigator.pop(context);
                _editController.clear();
              }
            },
            child: const Text('保存'),
          ),
        ],
      ),
    );
  }

  // 删除Todo的确认弹窗
  void _handleDeleteTodo(String id) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('确认删除'),
        content: const Text('你确定要删除这个待办项吗?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () {
              setState(() {
                _todos.removeWhere((t) => t.id == id);
              });
              Navigator.pop(context);
            },
            child: const Text('删除'),
          ),
        ],
      ),
    );
  }

  // 切换完成状态
  void _handleToggleComplete(Todo updatedTodo) {
    setState(() {
      final index = _todos.indexWhere((t) => t.id == updatedTodo.id);
      if (index != -1) {
        _todos[index] = updatedTodo;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Todo应用')),
      body: ListView.builder(
        itemCount: _todos.length,
        itemBuilder: (context, index) {
          final todo = _todos[index];
          return TodoItem(
            todo: todo,
            onEdit: _handleEditTodo,
            onDelete: _handleDeleteTodo,
            onToggleComplete: _handleToggleComplete,
          );
        },
      ),
      // 可选:新增Todo的按钮(可自行补充弹窗逻辑)
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
    );
  }
}

核心逻辑说明

  • 把列表项的UI和操作逻辑封装到TodoItem组件,代码更简洁易维护
  • 通过回调函数将组件内的操作事件传递给父页面,统一管理状态更新
  • 编辑、删除操作直接复用你已经在用的AlertDialog,不需要额外学习新组件

内容的提问来源于stack exchange,提问作者Danteon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 05:45:35