Flutter实现SVG动画按钮:点击触发动画播放方案咨询
Flutter SVG动画按钮实现方案
步骤1:添加依赖
在pubspec.yaml中引入支持SVG动画的包,并声明资源路径:
dependencies: flutter: sdk: flutter flutter_svg: ^2.0.9 # 可替换为最新版本 assets: - assets/images/icons/ - assets/animations/
步骤2:修改代码实现点击触发动画
替换原有的静态图片逻辑,引入动画控制器并绑定SVG播放:
import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State createState() => _Home(); } class _Home extends State<HomeScreen> with SingleTickerProviderStateMixin { Color background_color = Colors.red; final String _staticBamboo = 'assets/images/icons/OngQue.png'; final String _animatedBamboo = 'assets/animations/OngQue.svg'; late AnimationController _animationController; bool _isAnimating = false; @override void initState() { super.initState(); // 初始化动画控制器,时长匹配你的SVG动画实际长度 _animationController = AnimationController( vsync: this, duration: const Duration(seconds: 1), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } void _playAnimation() { setState(() => _isAnimating = true); _animationController.forward().then((_) { // 动画结束后重置控制器,恢复静态图 _animationController.reset(); setState(() => _isAnimating = false); }); } @override Widget build(BuildContext context) { final double bambooSize = MediaQuery.of(context).size.width * 0.9; return Container( color: background_color, child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: [ Flexible( child: GestureDetector( onTap: _playAnimation, child: _isAnimating ? SvgPicture.asset( _animatedBamboo, width: bambooSize, height: bambooSize, allowDrawingOutsideViewBox: true, // SVG加载时显示静态图作为占位 placeholderBuilder: (_) => Image.asset( _staticBamboo, width: bambooSize, height: bambooSize, ), controller: _animationController, ) : Image.asset( _staticBamboo, width: bambooSize, height: bambooSize, ), ), ), const SizedBox(height: 20), ], ), ); } }
关键说明
- 使用
flutter_svg包加载SVG动画:原生Image组件不支持SVG动画播放,该包支持SMIL格式的SVG动画。 - 动画控制器管理播放状态:点击时触发动画向前播放,结束后重置控制器并切换回静态图,保证每次点击都能完整播放一次动画。
- 用
GestureDetector替代IconButton:更灵活控制点击区域,避免尺寸适配问题。
注意事项
- 确保你的SVG动画是SMIL格式:CSS驱动的SVG动画无法被
flutter_svg识别,需要提前转换为SMIL。 - 同步动画时长:
AnimationController的duration要和SVG动画的实际时长一致,避免播放不同步。 - 资源路径正确:
pubspec.yaml中必须声明SVG所在的assets目录,否则会出现加载失败。
内容的提问来源于stack exchange,提问作者ManDo
相关产品推荐
相关产品推荐

