You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否实现侧边方向的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:31:15