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

Flutter待办列表页面刷新后任务数据重置丢失问题

问题根因

你把任务列表L、输入框显隐状态b都定义在了Tasks这个StatefulWidget的属性上,这是刷新后数据丢失的核心原因:

Flutter在触发组件重建(热重载、父组件重绘、键盘弹出收起触发的视图刷新等场景)时,会重新初始化Widget实例的所有属性,你之前追加到L里的新增任务,会被直接重置成初始传入的默认值。

另外你直接修改widget.L的写法也不符合Flutter设计规范:Widget本身是不可变的配置载体,直接修改它持有的属性本身就会导致状态不可控。

修复步骤
  • 将组件内部需要维护的可变状态(任务列表、输入框显隐状态)全部移动到对应的_TasksState类中,不要在Widget层存储会变化的数据
  • 新增任务时直接修改State内部维护的列表,再通过setState触发UI更新
  • 修正代码里的拼写问题:任务类的tite字段拼写错误,类名tasks按照Dart规范应当首字母大写,避免和组件类名重名可以命名为TaskItem
修复后可直接运行的代码
// 修正任务实体类的命名和字段拼写
class TaskItem {
  final String title;
  final List subTasks;
  TaskItem(this.title, this.subTasks);
}

class Tasks extends StatefulWidget {
  // 仅作为初始化传参入口,不在这里存储可变状态
  final List<TaskItem> initTasks;
  final bool initInputVisible;

  const Tasks(this.initTasks, this.initInputVisible, {super.key});

  @override
  State<Tasks> createState() => _TasksState();
}

class _TasksState extends State<Tasks> {
  final TextEditingController ctrl = TextEditingController();
  // 可变状态全部存在State中,组件重建时不会丢失
  late List<TaskItem> taskList;
  late bool inputVisible;

  @override
  void initState() {
    super.initState();
    // 初始化时读取widget传入的初始值
    taskList = List.from(widget.initTasks);
    inputVisible = widget.initInputVisible;
  }

  @override
  void dispose() {
    ctrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Visibility(
        maintainInteractivity: true,
        maintainState: true,
        maintainSize: true,
        maintainAnimation: true,
        visible: inputVisible,
        child: TextField(
          controller: ctrl,
          focusNode: FocusNode(descendantsAreFocusable: true),
          onSubmitted: (text) {
            if (text.trim().isEmpty) return;
            setState(() {
              // 修改State内部维护的列表
              taskList.add(TaskItem(text.trim(), []));
              ctrl.clear();
            });
          },
          decoration: const InputDecoration(fillColor: Colors.white, hintText: "输入任务后回车提交"),
          style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w400),
        ),
      ),
      Expanded(
        child: ListView.builder(
          itemCount: taskList.length,
          itemBuilder: (BuildContext context, int index) {
            return Card(
              color: Colors.black,
              child: Column(
                children: [
                  ListTile(
                    textColor: Colors.white,
                    iconColor: Colors.white,
                    title: Row(children: [
                      Checkbox(
                        value: false,
                        checkColor: const Color.fromRGBO(85, 85, 85, 1),
                        tristate: false,
                        onChanged: (value) {},
                      ),
                      Text(taskList[index].title)
                    ]),
                  ),
                ],
              ),
            );
          },
        )
      )
    ]);
  }
}
额外说明

如果后续需要从父组件修改任务列表、控制输入框显隐,通过didUpdateWidget生命周期监听父组件传入的新配置,同步更新State内部的状态即可,不要直接把可变状态存在Widget属性上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:57:27