You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现仅允许单个面板展开的自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:00:56