Flutter:删除ExpansionTile所有ListTile元素避免Bad state异常
解决ExpansionTile删除所有元素时的Bad state异常问题
问题根源很明确:你直接调用了test.first——当列表为空时,这个方法会直接抛出Bad state: No element异常,因为没有元素可以获取。要保留ExpansionTile的同时避免报错,核心是在构建UI时先判断列表是否为空,动态生成对应的children内容,而不是硬取first元素。
修改方案
直接调整ExpansionTile的children部分,根据列表状态动态渲染内容:
class GroupsNew extends StatefulWidget { const GroupsNew({super.key}); @override State<GroupsNew> createState() => _GroupsNewState(); } class _GroupsNewState extends State<GroupsNew> { bool _customIcon = false; List<String> test = ["string"]; @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: const EdgeInsets.all(14.0), child: ExpansionTile( title: const Text("分组列表"), leading: Icon(_customIcon ? Icons.expand_less : Icons.expand_more), children: test.isNotEmpty // 列表有元素时,遍历生成对应ListTile(支持展示多个元素) ? test.map((item) => ListTile( title: Text(item, style: const TextStyle(fontSize: 20)), trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () { setState(() { test.remove(item); }); }, ), )).toList() // 列表为空时,显示占位提示(也可替换为SizedBox.shrink()实现空内容) : [const ListTile(title: Text("暂无分组"))], onExpansionChanged: (bool expanded) { setState(() => _customIcon = expanded); }, ), ), ); } }
关键修改点
- 规避
test.first的风险:通过test.isNotEmpty判断列表状态,为空时完全跳过元素访问操作 - 动态适配children:
- 列表有元素时,用
map遍历所有元素生成ListTile,满足你“展示多个列表元素”的需求 - 列表为空时,返回占位提示或空Widget,确保ExpansionTile本身正常渲染
- 列表有元素时,用
- 优化删除逻辑:直接删除当前点击的
item,而非固定删除第一个元素,更贴合多元素场景的操作逻辑
这样修改后,无论列表是否为空,ExpansionTile都能正常显示,不会再抛出异常。
内容的提问来源于stack exchange,提问作者Tech RCV
相关产品推荐
相关产品推荐

