实现仅允许单个面板展开的自定义Expansion Tile技术咨询
实现仅允许单个面板展开的Expansion Tile
核心问题修正
你当前的代码逻辑存在状态同步问题:关闭面板时直接将selected设为-1,但如果未将Expansion Tile的展开状态与selected变量绑定,就会出现面板状态与预期不符的情况。以下是完整解决方案:
完整实现代码
class SingleExpandList extends StatefulWidget { const SingleExpandList({super.key}); @override State<SingleExpandList> createState() => _SingleExpandListState(); } class _SingleExpandListState extends State<SingleExpandList> { // 记录当前展开的面板索引,null表示无面板展开 int? _selectedIndex; @override Widget build(BuildContext context) { return ListView.builder( itemCount: 6, itemBuilder: (context, index) { return ExpansionTile( title: Text("面板 ${index + 1}"), // 绑定展开状态:当前索引等于选中索引时展开 initiallyExpanded: _selectedIndex == index, onExpansionChanged: (isExpanded) { setState(() { if (isExpanded) { // 展开当前面板,更新选中索引 _selectedIndex = index; } else { // 关闭当前面板,清空选中索引 _selectedIndex = null; } }); }, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Text("这是面板 ${index + 1} 的展开内容"), ), ], ); }, ); } }
关键注意点
- 状态绑定:必须将
ExpansionTile的initiallyExpanded属性与_selectedIndex关联,确保面板展开状态和变量同步。 - 逻辑优化:使用可空类型
int?代替-1作为默认值,代码更清晰,避免魔法数字。 - 可选逻辑调整:如果希望点击已展开的面板时无法手动关闭,只能通过切换其他面板收起,可修改
onExpansionChanged逻辑:onExpansionChanged: (isExpanded) { setState(() { // 仅在展开时更新选中索引,关闭时不修改 if (isExpanded) _selectedIndex = index; }); }
内容的提问来源于stack exchange,提问作者rasheed
相关产品推荐
相关产品推荐

