在GetX中使用GetTickerProviderStateMixin实现AnimationController动画失败求助
问题原因及解决方法
你的动画无法启动的核心原因是:动画值变化时没有触发Widget重建。Getx的响应式机制需要明确通知UI更新,而你当前的代码中,Animation的数值变化不会自动触发GetView的build方法重新执行。
第一步:修改TestAnimationController
给Animation添加监听器,在值变化时调用update()通知Getx刷新UI,同时别忘了在控制器销毁时释放AnimationController:
class TestAnimationController extends GetxController with GetTickerProviderStateMixin { late AnimationController anim; late Animation<double> animation; @override void onInit() { super.onInit(); initAnimation(); anim.forward(); } void initAnimation() { anim = AnimationController( duration: const Duration(seconds: 1), vsync: this, ); animation = Tween<double>(begin: 1, end: 0).animate( CurvedAnimation( parent: anim, curve: const Interval(0.0, 1.0, curve: Curves.linear), ), )..addListener(() { update(); // 通知UI更新 }); } @override void onClose() { anim.dispose(); // 释放动画控制器,避免内存泄漏 super.onClose(); } }
第二步:修改TestAnimationHome
用GetBuilder包裹需要动画的Container,它会监听Controller的update()调用并重建子Widget。同时注意点击FAB时要先重置动画,否则已完成的动画无法再次执行:
class TestAnimationHome extends GetView<TestAnimationController> { const TestAnimationHome({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GetBuilder<TestAnimationController>( builder: (ctrl) { return Container( width: ctrl.animation.value + 100, height: ctrl.animation.value + 100, color: Colors.amber, ); }, ), ), floatingActionButton: FloatingActionButton( onPressed: () { controller.anim.reset(); // 重置动画到初始状态 controller.anim.forward(); // 重新执行动画 }, child: const Icon(Icons.play_circle), ), ); } }
额外说明
- 如果你想用Rx响应式的方式,也可以把
animation定义为Rx<Animation<double>>,然后用Obx监听,效果是一样的,addListener+update()的方式更直接适配原生Animation。 - 一定要在
onClose()里释放AnimationController,这是Flutter动画开发的基本规范,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Tofiq Samali
相关产品推荐
相关产品推荐

