如何实现带数字的小球滚动到左端时停止AnimatedPositioned动画?
实现小球滚动到左端后停止动画的解决方案
当前代码存在两个核心问题:
AnimatedPositioned的left值直接在Get.width和0之间跳变,没有平滑过渡,也无法监听位置变化过程firstAnimationController.repeat()导致旋转动画无限循环,没有停止逻辑
以下是具体修复方案:
1. 重构控制器,添加位置动画与状态监听
创建专门驱动小球位置的Animation,并监听动画完成状态,到达左端时自动停止动画。
late AnimationController firstAnimationController; late Animation<double> leftAnimation; RxBool isFirstStarted = false.obs; @override void onInit() async { super.onInit(); firstAnimationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 1000), ); // 定义从屏幕宽度到0的位置过渡动画 leftAnimation = Tween<double>( begin: Get.width, end: 0, ).animate(firstAnimationController); // 监听动画状态,完成时停止控制器 firstAnimationController.addStatusListener((status) { if (status == AnimationStatus.completed) { firstAnimationController.stop(); isFirstStarted.value = false; } }); } @override void dispose() { firstAnimationController.dispose(); super.dispose(); } // 触发动画的方法 void startBallAnimation() { isFirstStarted.value = true; firstAnimationController.forward(from: 0); }
2. 修改UI组件,用动画驱动位置与旋转
移除AnimatedPositioned,改用Positioned绑定动画值,同时让旋转角度与移动进度同步,避免独立旋转的问题。
Container( width: Get.width, height: 90, padding: const EdgeInsets.only(top: 10, bottom: 10), decoration: const BoxDecoration( border: Border(top: BorderSide(color: Colors.black, width: 1), bottom: BorderSide(color: Colors.black, width: 1)) ), child: Stack( alignment: Alignment.center, children: [ AnimatedBuilder( animation: controller.leftAnimation, builder: (context, widget) { return Positioned( left: controller.isFirstStarted.value ? controller.leftAnimation.value : Get.width, child: Transform.rotate( // 按移动进度计算旋转角度,保持原逻辑的一圈6.3弧度 angle: -controller.leftAnimation.value / Get.width * 6.3, child: Container( width: 60, height: 60, alignment: Alignment.center, decoration: BoxDecoration( border: Border.all(color: Colors.black, width: 1), borderRadius: BorderRadius.circular(30), color: Colors.white, ), child: const Text('37', style: TextStyle(fontSize: 20) )) ) ); } ), ] ), );
核心逻辑说明
- 通过
Tween和Animation实现平滑的位置过渡,同时能通过AnimationStatus.completed精确感知小球到达左端(left=0)的时刻 - 旋转角度与移动进度绑定,确保小球移动和旋转同步,不会出现无限旋转的情况
- 调用
startBallAnimation()即可启动动画,到达终点后自动停止
内容的提问来源于stack exchange,提问作者dfassf
相关产品推荐
相关产品推荐

