Flutter中CheckboxListTile所有复选框同步选中问题求助
问题解决:实现复选框单独控制选中状态
问题原因
你当前所有复选框的选中状态都绑定了同一个全局变量timeDilation,所有CheckboxListTile的value都依赖timeDilation !=1.0,所以点击任意一个复选框时,全局变量改变,所有复选框的状态都会同步变化,导致全部同时选中/取消。
修改步骤
在主Widget的状态类中维护独立的选中状态列表
给_MainWidgetState添加一个List<bool>类型的变量,用来存储每个列表项的选中状态,初始化时长度和ModelList一致,默认全部未选中。绑定复选框到对应索引的状态
将CheckboxListTile的value改为对应索引的状态值,onChanged时仅更新当前索引的状态。
修改后的完整代码
// 模型类保持不变 import 'package:flutter/material.dart'; class Info { String title; String description; Info({required this.title, required this.description}); } List<Info> ModelList = [ Info(title: 'title1', description: 'description1'), Info(title: 'title2', description: 'description2'), ]; // 主Widget修改 class MainWidget extends StatefulWidget { const MainWidget({Key? key}) : super(key: key); @override State<MainWidget> createState() => _MainWidgetState(); } class _MainWidgetState extends State<MainWidget> { // 维护每个列表项的选中状态,初始全为false late List<bool> _isChecked; @override void initState() { super.initState(); _isChecked = List.generate(ModelList.length, (index) => false); } @override Widget build(BuildContext context) { return Scaffold( body: ListView.builder( itemCount: ModelList.length, itemBuilder: (context, index) { Info cardname = ModelList[index]; return Card( child: CheckboxListTile( tileColor: const Color(0xFF5D6D7E), shape: RoundedRectangleBorder( side: const BorderSide(color: Colors.white, width: 2), borderRadius: BorderRadius.circular(10), ), contentPadding: const EdgeInsets.symmetric(vertical: 10.0), // 绑定当前索引的选中状态 value: _isChecked[index], onChanged: (bool? value) { setState(() { // 仅更新当前索引的状态 _isChecked[index] = value!; // 如果需要保留timeDilation的动画逻辑,可单独处理,比如: // timeDilation = value ? 5.0 : 1.0; // 但注意这仍会全局改变动画速度,建议根据需求调整 }); }, title: Text( cardname.title, style: const TextStyle( fontSize: 25.0, fontWeight: FontWeight.w600, color: Colors.white), ), controlAffinity: ListTileControlAffinity.leading, secondary: IconButton( icon: const Icon(Icons.info_outlined, size: 40, color: Colors.orange), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => DetailScreen(cardname)), ); }, ), ), ); }, ), ); } } // 详情页保持不变(替换自定义appBar为标准AppBar,若有自定义实现可自行替换) class DetailScreen extends StatelessWidget { final Info cardname; const DetailScreen(this.cardname, {super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(cardname.title)), body: Padding( padding: const EdgeInsets.all(8.0), child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text( cardname.description, textAlign: TextAlign.justify, style: const TextStyle(fontSize: 22.0), ), ), ], ), ), ), ); } }
补充说明
- 你之前尝试的子Widget方案无效,是因为子Widget仍然没有为每个列表项维护独立的状态,只是把列表构建移到了子Widget,本质还是共享同一个全局状态。
- 如果
timeDilation是用于动画慢动作效果,建议不要用它控制复选框状态,二者职责分离更合理。
内容的提问来源于stack exchange,提问作者datavinnie
相关产品推荐
相关产品推荐

