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

Flutter动态添加的CheckboxListTile复选框无法勾选问题求解

问题根因

你的代码存在4个核心问题,直接导致复选框无法正常工作:

  • 所有待办项共用同一个勾选状态变量:你在_ToDosState的build方法中只定义了1个bool checked = false,循环生成的所有CheckboxListTile全部绑定这个变量,点击任意复选框都会修改这一个值,无法实现单条目独立勾选。
  • 状态变量定义位置错误:你把checked定义在build方法内部,每次组件触发重绘(比如新增待办、点击复选框调用setState),build方法重新执行时都会把checked重置为初始的false,修改后的状态根本无法留存。
  • 冗余组件使用错误:_ToDosState本身就是StatefulWidget对应的状态类,自带可触发刷新的setState方法,你额外嵌套的StatefulBuilder完全多余,反而打乱了状态更新的范围。
  • 数据结构设计缺陷:你当前的待办列表只存储了待办文本内容,没有给每个待办项绑定独立的勾选状态属性,本质上是数据和视图状态脱节。另外你把toDoList、userInput、文本控制器都定义为顶层全局变量,很容易出现跨组件状态不同步、内存泄漏问题,初始化时var toDoList = <String>[userInput];还存在初始化顺序错误(变量定义时userInput还未赋值)。
修复步骤
  1. 先定义待办项的数据结构,把文本内容和勾选状态绑定为一个整体:
// 可放在to_do_section.dart顶部
class ToDoItem {
  final String content;
  bool isChecked;
  ToDoItem({required this.content, this.isChecked = false});
}
  1. 修改landing_page.dart,把全局变量移到对应State类内部,新增待办后清空输入框:
import 'package:flutter/material.dart';
import 'package:flutter_application_1/presentation/widgets/to_do_section.dart';

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

  @override
  State<LandingPage> createState() => _LandingPageState();
}

class _LandingPageState extends State<LandingPage> {
  // 把原顶层变量移到State内部
  final _textController = TextEditingController();
  String userInput = "";
  // 列表改为存储ToDoItem类型
  List<ToDoItem> toDoList = [];

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Center(child: Text("To-Do-App")),
        backgroundColor: Colors.redAccent,
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [ToDos(list: toDoList), ToDoAdd()],
        ),
      ),
    );
  }

  Column ToDoAdd() {
    return Column(
      children:  [
        Padding(
          padding: EdgeInsets.only(top: 8.0, left: 20, right: 20, bottom: 20),
          child: TextField(
            controller: _textController,
            onChanged: (value) => setState(() => userInput = value),
            textAlign: TextAlign.center,
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              hintText: "Add a new ToDo",
            ),
          ),
        ),
        MaterialButton(
          color: Colors.redAccent,
          onPressed: () {
            if(userInput.trim().isEmpty) return;
            setState(() {
              toDoList.add(ToDoItem(content: userInput.trim()));
              // 新增后清空输入框
              userInput = "";
              _textController.clear();
            });
          },
          child: Text("Add", style: TextStyle(color: Colors.white),),
        ),
        Text(userInput)
      ],
    );
  }
}
  1. 修改to_do_section.dart,去掉冗余的StatefulBuilder和局部状态变量,每个复选框绑定对应待办项自己的勾选状态:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_application_1/responsive_layout.dart';

// 待办项模型放这里也可以
class ToDoItem {
  final String content;
  bool isChecked;
  ToDoItem({required this.content, this.isChecked = false});
}

class ToDos extends StatefulWidget {
  final List<ToDoItem> list;
  const ToDos({
    Key? key,
    required this.list,
  }) : super(key: key);

  @override
  State<ToDos> createState() => _ToDosState();
}

class _ToDosState extends State<ToDos> {
  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    // 去掉多余的局部checked变量、StatefulBuilder
    return Padding(
      padding: EdgeInsets.only(
          top: SizeConfig.blockSizeHorizontal * 10,
          left: SizeConfig.blockSizeVertical * 2.5,
          right: SizeConfig.blockSizeVertical * 2.5,
          bottom: SizeConfig.screenHeight / 8),
      child: SizedBox(
        width: SizeConfig.blockSizeHorizontal * 100,
        height: SizeConfig.blockSizeVertical * 40,
        child: Container(
          decoration: BoxDecoration(
              color: Colors.grey[400],
              borderRadius: BorderRadius.circular(30),
              border: Border.all(
                  color: Colors.black45, style: BorderStyle.solid, width: 4)),
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: ToDoColumn(),
          ),
        ),
      ),
    );
  }

  Column ToDoColumn() {
    return Column(children: [
      for (int i = 0; i < widget.list.length; i++)
        CheckboxListTile(
          // 绑定当前待办项自己的勾选状态
          value: widget.list[i].isChecked,
          onChanged: (newValue) {
            setState(() {
              // 只修改当前项的状态
              widget.list[i].isChecked = newValue!;
            });
          },
          title: Text(widget.list[i].content),
          activeColor: Colors.green,
          checkColor: Colors.black,
        )
    ]);
  }
}

改完之后每个待办项的勾选状态独立存储、独立更新,不会再出现点不动或者全选全不选的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:36:20