如何让Flutter ExpansionTile的Trailing图标右上对齐?
如何让Flutter的ExpansionTile组件Trailing图标右上对齐?
ExpansionTile的默认Trailing图标是居中对齐的,要实现右上对齐的效果,你可以通过自定义Trailing组件来实现,同时保留默认的展开/收起动画效果,具体步骤如下:
解决方法
- 维护状态变量跟踪ExpansionTile的展开状态
- 用
Align组件包裹图标,设置alignment: Alignment.topRight实现右上对齐 - 配合
Transform.rotate实现图标的展开/收起旋转动画
修改后的完整代码
class MyExpansionTile extends StatefulWidget { const MyExpansionTile({super.key}); @override State<MyExpansionTile> createState() => _MyExpansionTileState(); } class _MyExpansionTileState extends State<MyExpansionTile> { bool _isExpanded = false; @override Widget build(BuildContext context) { return ClipRRect( borderRadius: BorderRadius.circular(4), child: ExpansionTile( tilePadding: EdgeInsets.all(15), collapsedBackgroundColor: Color.fromRGBO(24, 34, 62, 1), backgroundColor: Color.fromRGBO(24, 34, 62, 1), iconColor: Colors.white, collapsedIconColor: Colors.white, expandedCrossAxisAlignment: CrossAxisAlignment.start, // 监听展开状态变化 onExpansionChanged: (value) { setState(() { _isExpanded = value; }); }, // 自定义右上对齐的Trailing图标 trailing: Align( alignment: Alignment.topRight, child: Transform.rotate( // 根据展开状态旋转图标,模拟默认动画 angle: _isExpanded ? 3.14159 / 2 : 0, child: Icon(Icons.expand_more, color: Colors.white), ), ), title: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "text".toUpperCase(), style: TextStyle( color: Color.fromARGB(255, 14, 248, 26), ), ), const SizedBox(width: 12), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'How to make trailing icon top align ', style: TextStyle( fontWeight: FontWeight.w600, color: Color.fromRGBO(0, 249, 85, 1), fontSize: 12), ), Container( margin: const EdgeInsets.only(top: 3), constraints: const BoxConstraints(minWidth: 80), decoration: BoxDecoration( color: Color.fromRGBO(226, 80, 95, 1), borderRadius: BorderRadius.circular(2)), padding: const EdgeInsets.symmetric(vertical: 2), child: Text( 'label', textAlign: TextAlign.center, style: TextStyle( color: Colors.black, fontSize: 10, fontWeight: FontWeight.w600), ), ) ], ), Text( '40%', style: TextStyle( fontSize: 20, color: Color.fromARGB(255, 14, 248, 26), fontWeight: FontWeight.w700), ) ], ), ) ], ) ], ), children: const <Widget>[ ListTile(title: Text('This is tile number 1')), ], ), ); } }
关键说明
Align(alignment: Alignment.topRight):将图标固定在Trailing区域的右上角Transform.rotate:根据ExpansionTile的展开状态_isExpanded旋转图标,还原默认的展开/收起动画逻辑onExpansionChanged:监听组件展开/收起事件,同步更新图标状态
内容的提问来源于stack exchange,提问作者gaurav kerkar
相关产品推荐
相关产品推荐

