能否实现侧边方向的FadeTransition?如何实现左右上下方向淡入过渡?
当然可以实现!原生的FadeTransition本身只负责控制透明度渐变,没有内置方向相关逻辑,但咱们可以通过**组合SlideTransition和FadeTransition**的方式,轻松搞定从左、右、上、下任意方向发起的淡入淡出过渡,效果完全能匹配你提到的示例风格~
核心实现思路
我们要的是「从目标方向滑入 + 同步淡入」的组合效果,所以可以用同一个AnimationController驱动两个动画:
- 一个给
SlideTransition控制偏移量,让组件从屏幕外的目标方向移动到指定位置 - 另一个给
FadeTransition控制透明度,让组件从完全透明渐变到完全可见
可复用组件代码示例
下面是一个封装好的自定义过渡组件,支持指定任意方向,直接拿来用就行:
import 'package:flutter/material.dart'; // 定义过渡方向枚举 enum SlideFadeDirection { left, right, top, bottom, } class SlideFadeTransition extends StatefulWidget { final Widget child; final SlideFadeDirection direction; final Duration duration; final Curve curve; final bool autoStart; const SlideFadeTransition({ super.key, required this.child, this.direction = SlideFadeDirection.right, this.duration = const Duration(milliseconds: 500), this.curve = Curves.easeInOut, this.autoStart = true, }); @override State<SlideFadeTransition> createState() => _SlideFadeTransitionState(); } class _SlideFadeTransitionState extends State<SlideFadeTransition> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _fadeAnim; late Animation<Offset> _slideAnim; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: widget.duration, ); // 根据方向设置初始偏移(从屏幕外的对应位置开始) Offset initialOffset; switch (widget.direction) { case SlideFadeDirection.left: initialOffset = const Offset(-1.0, 0.0); break; case SlideFadeDirection.right: initialOffset = const Offset(1.0, 0.0); break; case SlideFadeDirection.top: initialOffset = const Offset(0.0, -1.0); break; case SlideFadeDirection.bottom: initialOffset = const Offset(0.0, 1.0); break; } // 创建透明度和偏移动画 _fadeAnim = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _controller, curve: widget.curve), ); _slideAnim = Tween<Offset>(begin: initialOffset, end: Offset.zero).animate( CurvedAnimation(parent: _controller, curve: widget.curve), ); // 自动启动动画(可通过参数关闭) if (widget.autoStart) { _controller.forward(); } } // 暴露手动控制动画的方法 void play() => _controller.forward(); void reverse() => _controller.reverse(); @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return FadeTransition( opacity: _fadeAnim, child: SlideTransition( position: _slideAnim, child: widget.child, ), ); } }
使用示例
直接把需要加过渡的Widget包在这个组件里,指定方向即可:
// 从右侧滑入淡入的蓝色容器 SlideFadeTransition( direction: SlideFadeDirection.right, child: Container( width: 200, height: 200, color: Colors.blue, alignment: Alignment.center, child: const Text('右侧淡入滑入', style: TextStyle(color: Colors.white, fontSize: 16)), ), )
额外优化小技巧
- 如果要在页面路由切换时用这个效果,可以自定义
PageRouteBuilder,把上述过渡逻辑集成进去 - 调用
reverse()方法可以实现反向效果(比如淡出并滑回原方向) - 调整
curve参数能改变动画缓动风格,比如Curves.fastOutSlowIn会让动画更自然流畅 - 如果需要延迟启动动画,可以在
initState里加Future.delayed(const Duration(milliseconds: 300), () => _controller.forward())
这样就完全实现了你想要的从不同方向发起的淡入过渡效果啦!
内容的提问来源于stack exchange,提问作者Roku
相关产品推荐
相关产品推荐

