Flutter中点击单个Expansion Tile时关闭其余展开项的实现方法
实现单个ExpansionTile展开时自动关闭其他项
你的现有代码用单个布尔值控制所有ExpansionTile的展开状态,无法区分不同项的状态,因此需要通过跟踪当前展开项的索引来实现互斥展开的效果,具体修改如下:
修改步骤
- 将原来的
bool initiallyExpanded替换为int? _expandedIndex,用于存储当前展开项的索引,初始值为null表示无展开项。 - 每个
ExpansionTile的展开状态由expanded: index == _expandedIndex控制,而非固定的initiallyExpanded。 - 在
onExpansionChanged回调中更新索引:当项被展开时,将_expandedIndex设为当前项的索引;当项被关闭时,将_expandedIndex设为null。
完整代码
import 'package:flutter/material.dart'; class PickPlanPage extends StatefulWidget { const PickPlanPage({Key? key}) : super(key: key); @override State<PickPlanPage> createState() => _PickPlanPageState(); } class _PickPlanPageState extends State<PickPlanPage> { // 存储当前展开项的索引,null表示无展开项 int? _expandedIndex; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: ListView.separated( itemCount: 5, separatorBuilder: (context, index) => const SizedBox(height: 20), itemBuilder: (context, index) => ExpansionTile( // 根据当前索引判断是否展开 expanded: index == _expandedIndex, title: const Text('title'), onExpansionChanged: (isExpanded) { setState(() { // 展开时记录当前索引,关闭时清空 _expandedIndex = isExpanded ? index : null; }); }, children: const [ Text('Description'), ], ), ), ); } }
说明
这样修改后,每次点击一个ExpansionTile展开时,其他已展开的项会自动关闭;点击已展开的项则会关闭它自己,实现了互斥展开的需求。
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

