如何让Flutter ExpansionTile的自定义尾部SVG图标实现旋转效果?
问题修复方案
ExpansionTile原生自带的尾部图标旋转效果是框架内部针对默认图标单独实现的,自定义传入的trailing组件不会自动绑定该动画,因此需要自行监听展开状态并为SVG图标添加旋转动画。
具体修改步骤
- 将原Stateless的ExpansionTileCard改为StatefulWidget,用于维护组件的展开/折叠状态
- 绑定ExpansionTile的
onExpansionChanged回调,实时更新展开状态 - 使用
AnimatedRotation隐式动画组件包裹自定义SVG图标,根据展开状态控制旋转角度,动画时长与ExpansionTile原生动画保持一致(200ms)即可实现完全同步的效果
修改后的完整代码
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; class ExpansionTileCard extends StatefulWidget { final String toptitle; final List<Widget> children; const ExpansionTileCard({super.key, required this.toptitle, required this.children}); @override State<ExpansionTileCard> createState() => _ExpansionTileCardState(); } class _ExpansionTileCardState extends State<ExpansionTileCard> { // 保存展开状态 bool _isExpanded = false; @override Widget build(BuildContext context) { return Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.green))), child: Row( children: [ Expanded( flex: 9, child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExpansionTile( onExpansionChanged: (value) { // 监听展开状态变化更新状态 setState(() { _isExpanded = value; }); }, title: Text( widget.toptitle, style: TextStyle( color: Colors.black, letterSpacing: -1, fontSize: 19, fontWeight: FontWeight.bold), ), children: widget.children, childrenPadding: EdgeInsets.fromLTRB(0, 0, 0, 20), iconColor: Colors.green, // 用AnimatedRotation包裹SVG实现旋转动画 trailing: AnimatedRotation( turns: _isExpanded ? 0.25 : 0, // 0.25对应顺时针旋转90度,和原生效果一致 duration: Duration(milliseconds: 200), // 和ExpansionTile原生动画时长一致 child: SvgPicture.asset( 'assets/icons/textmessage.svg', height: 30, ), ), ), ], ), ), ) ], ), ), ], ), ); } }
如果需要调整旋转方向、角度,直接修改turns的参数即可,比如_isExpanded ? -0.25 : 0就是逆时针旋转90度。
内容的提问来源于stack exchange,提问作者Mr Man
相关产品推荐
相关产品推荐

