Flutter:实现点击其他ExpansionTileCard时关闭已展开卡片
解决Flutter中ExpansionTileCard互斥展开的问题
要实现点击新卡片时自动收起之前展开的卡片,核心思路是用一个全局变量记录当前展开的卡片ID,通过这个变量统一控制所有ExpansionTileCard的展开状态。具体修改步骤如下:
- 在你的页面State类中添加状态变量,用来保存当前展开的订单ID:
String? _expandedOrderId;
- 修改
_listItemColumn方法里的ExpansionTileCard配置,绑定展开状态并处理点击事件:
child: ExpansionTileCard( // 用当前卡片ID和_expandedOrderId对比,控制是否展开 expanded: _expandedOrderId == id, initiallyExpanded: false, title: Text(name), subtitle: Text(date), trailing: Wrap( spacing: 12, children: <Widget>[ Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ Material( color: Colorz.transparents, child: InkWrapper( splashColor: Colorz.lighterGray, child: IconButton( alignment: Alignment.center, icon: SvgPicture.asset( Img.listItemMenu, ), onPressed: null ), onTap: () { }, ), ), Text( status, textAlign: TextAlign.left, maxLines: 1, style: TextStyle( color: _colorStatus(status), overflow: TextOverflow.ellipsis, fontSize: FontSize.tiny, ), ), ], ) ], ), // 处理展开/收起事件 onExpansionChanged: (isExpanded) { setState(() { _expandedOrderId = isExpanded ? id : null; }); }, children: [ _buildTextLine( Titles.orderMaster, null, master, ), Container( height: Margins.tiny, ) ], ),
注意事项
- 确保你的页面是
StatefulWidget,因为需要通过setState更新状态。如果原来的是StatelessWidget,需要改成StatefulWidget。 - 这里用订单ID作为唯一标识,也可以根据实际情况改用索引(position),只要能唯一区分每个卡片即可。
这样修改后,每次点击任意一个ExpansionTileCard,都会自动收起之前展开的卡片,只保留当前点击的卡片处于展开状态。
内容的提问来源于stack exchange,提问作者Andrii Havryliak
相关产品推荐
相关产品推荐

