Flutter Todo应用勾选单个项时全部选中问题及修复方法
Flutter Todo应用勾选问题修复及Key使用说明
问题描述
我开发了一个简易Flutter Todo应用,可将文本框输入内容添加至列表。但勾选列表中单个项时,所有项都会被勾选。我怀疑和Key有关,后续还打算将列表改为可重排列表,可能也需要用到Key。我是Flutter及编程新手,希望能了解问题原因并获得修复方案。
原代码
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: const TodoApp(), theme: ThemeData(primarySwatch: Colors.yellow), )); } class TodoApp extends StatefulWidget { const TodoApp({super.key}); @override State<TodoApp> createState() => _TodoAppState(); } class _TodoAppState extends State<TodoApp> { final _textyController = TextEditingController(); List<String> storedText = []; bool checkedValue = false; @override Widget build(context) { return Scaffold( backgroundColor: Colors.yellow[100], appBar: AppBar( title: const Text("Todo"), centerTitle: true, elevation: 0, ), body: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 15.0), child: Column( children: [ Expanded( child: ListView.builder( reverse: true, itemCount: storedText.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.yellow), child: Padding( padding: const EdgeInsets.all(8.0), child: CheckboxListTile( activeColor: Colors.black, controlAffinity: ListTileControlAffinity.leading, title: Text(storedText[index]), value: checkedValue, onChanged: (newCheckedValue) { setState(() { checkedValue = newCheckedValue!; }); }), ), ), ); }, ), ), Padding( padding: const EdgeInsets.symmetric(vertical: 20.0), child: TextField( controller: _textyController, onSubmitted: (value) { setState(() { storedText.insert(0, value); _textyController.clear(); }); }, decoration: const InputDecoration( labelText: '+ Add a task', labelStyle: TextStyle( color: Colors.grey, ), border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black), ), focusColor: Colors.blue, ), cursorColor: Colors.grey[400], ), ), ], )), ); } }
问题原因
代码中用单个bool变量checkedValue绑定所有CheckboxListTile的value属性,所有列表项共享同一状态,所以修改时所有项的选中状态会同步变化。
修复方案
- 创建Todo数据类,单独存储每个任务的文本和选中状态:
class Todo { String text; bool isChecked; Todo({required this.text, this.isChecked = false}); }
- 将原
List<String> storedText替换为List<Todo> todos = []; - 修改添加任务的逻辑:
todos.insert(0, Todo(text: value));
- 更新
CheckboxListTile的value和onChanged逻辑,绑定对应任务的选中状态:
value: todos[index].isChecked, onChanged: (newCheckedValue) { setState(() { todos[index].isChecked = newCheckedValue!; }); }
关于Key的说明
后续实现可重排列表时,需要为每个列表项设置唯一Key(比如ValueKey(todos[index].text)),帮助Flutter准确识别每个列表项的身份,避免重排时出现状态混乱的问题。
内容的提问来源于stack exchange,提问作者Hans Ramzan
相关产品推荐
相关产品推荐

