如何调整Flutter中Curves.bounceInOut动画方向实现指定弹跳效果
Flutter 弹跳球动画调整方案
问题分析
你当前的代码把垂直(bottom)和水平(left)方向的位置都绑定到了同一个动画值,且使用Curves.bounceInOut曲线,导致两个方向同步弹跳,形成斜向的往复运动,和预期的"指定方向弹跳曲线运动"不符。
调整方案
要实现类似弹跳球的效果,需要将垂直方向的弹跳动画和水平方向的平滑移动动画拆分,用同一个动画控制器驱动两个独立的动画:
1. 定义两个独立的动画
分别为垂直位置和水平位置创建动画,垂直方向使用弹跳曲线,水平方向使用线性曲线(或其他符合需求的曲线):
late Animation<double> _verticalAnimation; late Animation<double> _horizontalAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 3), // 可根据需求调整动画时长 vsync: this, ); // 垂直方向:从屏幕外下方弹入到指定位置,用bounceOut实现落地弹跳效果 _verticalAnimation = Tween<double>( begin: -250, // 圆形容器高度,初始状态完全在屏幕外 end: 50, // 最终距离屏幕底部的距离 ).animate( CurvedAnimation( parent: _controller, curve: Curves.bounceOut, ), ); // 水平方向:从左侧平滑移动到右侧,避免超出屏幕 _horizontalAnimation = Tween<double>( begin: 0, end: MediaQuery.sizeOf(context).width - 250, ).animate( CurvedAnimation( parent: _controller, curve: Curves.linear, ), ); _controller.forward(); }
2. 修改AnimatedBuilder中的Positioned参数
将bottom绑定到垂直动画,left绑定到水平动画,同时优化组件构建性能:
Stack( children: [ // 背景图片视图 Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('images/sky.webp'), fit: BoxFit.cover), ), ), AnimatedBuilder( animation: _controller, builder: (context, child) { return Positioned( bottom: _verticalAnimation.value, left: _horizontalAnimation.value, child: child!, ); }, // 将圆形容器作为child传入,避免动画帧重复构建容器 child: Container( height: 250, width: 250, decoration: const BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: AssetImage('images/colz.jpg'), fit: BoxFit.cover, ), ), ), ) ], )
额外调整建议
- 若需要"弹起-下落-再弹起"的循环效果,可以给动画控制器添加重复逻辑:
_controller.repeat(reverse: false); - 垂直方向可替换曲线:
Curves.bounceIn是弹起时的弹跳效果,Curves.bounceOut是落地时的弹跳效果,可根据需求切换
内容的提问来源于stack exchange,提问作者grunze shyangbo
相关产品推荐
相关产品推荐

