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

Flutter实现渐显滑动动画:SKYGOAL文本动画求助

问题描述

我正在Flutter应用中实现启动页效果,但无法实现“SKYGOAL”文本的渐显+滑动动画。已经用AnimatedContainer或AnimatedOpacity完成了其他组件的动画,作为动画新手不知道该怎么处理这个需求,求帮助!

当前相关代码片段:

class SplashScreen1 extends StatefulWidget {
  const SplashScreen1({Key? key}) : super(key: key);

  @override
  State<SplashScreen1> createState() => _SplashScreen1State();
}

class _SplashScreen1State extends State<SplashScreen1> with SingleTickerProviderStateMixin {
  double _skygoalLogoOpacity = 0;
  double _syjOpacity = 0;
  double _skygoalTextWidth = 0;

  @override
  void initState() {
    super.initState();
    Future.delayed(const Duration(seconds: 0)).then((value) => setState(() {
      _skygoalLogoOpacity = 1;
      _syjOpacity = 1;
      _skygoalTextWidth = 2000;
    }));
    Future.delayed(const Duration(milliseconds: 4800)).then((value) => Navigator.pushReplacement(context, AnimatedPageRoute(SplashScreen2())));
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Color(0xFF0E3C6E),
        width: MediaQuery.of(context).size.width,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: [
            SizedBox(height: 250,),
            Stack(
              children: [
                Container(
                  decoration: BoxDecoration(
                      shape: BoxShape.circle, color: Colors.white
                  ),
                  height: 185,
                  width: 185,
                ),
                AnimatedOpacity(
                  duration: const Duration(milliseconds: 1000),
                  opacity: _skygoalLogoOpacity,
                  child: Container(
                    padding: EdgeInsets.only(top: 20),
                    child: Image.asset("assets/images/skygoal-logo.png"),
                    width: 164,
                  ),
                ),
              ],
            ),
            Stack(
              children: [
                AnimatedOpacity(
                  duration: const Duration(milliseconds: 2000),
                  opacity: _syjOpacity,
                  child: Container(
                    margin: EdgeInsets.only(left: 40, top: 37),
                    height: 29,
                    width: 153,
                    child: Image.asset("assets/images/start-your-journey.png"),
                  ),
                ),
                Container(
                  margin: EdgeInsets.only(top: 5,left: 20),
                  child: Text(
                    "SKYGOAL",
                    style: GoogleFonts.poppins(
                      fontSize: 30,
                      fontWeight: FontWeight.w800,
                      color: Colors.white
                    ),
                    textAlign: TextAlign.center,
                  ),
                ),

              ],
            ),
            Spacer(),
            Text(
              "By Skygoal",
              style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold,
                fontSize: 13
              ),
            ),
            Container(
              margin: EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(10)
              ),
              height: 5,
              width: 134,
            )
          ],
        ),
      ),
    );
  }
}
解决方案

要实现文本的渐显+滑动组合动画,可以用AnimationController配合SlideTransition和FadeTransition的组合,以下是修改后的完整代码:

class SplashScreen1 extends StatefulWidget {
  const SplashScreen1({Key? key}) : super(key: key);

  @override
  State<SplashScreen1> createState() => _SplashScreen1State();
}

class _SplashScreen1State extends State<SplashScreen1> with SingleTickerProviderStateMixin {
  double _skygoalLogoOpacity = 0;
  double _syjOpacity = 0;
  // 新增动画控制器与动画对象
  late AnimationController _textAnimationController;
  late Animation<double> _textOpacityAnimation;
  late Animation<Offset> _textSlideAnimation;

  @override
  void initState() {
    super.initState();
    // 初始化动画控制器,时长可按需调整
    _textAnimationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1500),
    );

    // 渐显动画:从完全透明到完全显示
    _textOpacityAnimation = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: _textAnimationController, curve: Curves.easeInOut),
    );

    // 滑动动画:从左侧偏移位置滑到目标位置(可修改偏移量调整滑动方向)
    _textSlideAnimation = Tween<Offset>(begin: const Offset(-0.5, 0), end: Offset.zero).animate(
      CurvedAnimation(parent: _textAnimationController, curve: Curves.easeOut),
    );

    // 控制动画启动时机,配合其他组件动画节奏调整延迟
    Future.delayed(const Duration(milliseconds: 500), () {
      _textAnimationController.forward();
    });

    // 原有其他组件动画逻辑
    Future.delayed(const Duration(seconds: 0)).then((value) => setState(() {
      _skygoalLogoOpacity = 1;
      _syjOpacity = 1;
    }));

    Future.delayed(const Duration(milliseconds: 4800)).then((value) => Navigator.pushReplacement(context, AnimatedPageRoute(SplashScreen2())));
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    _textAnimationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: const Color(0xFF0E3C6E),
        width: MediaQuery.of(context).size.width,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: [
            const SizedBox(height: 250),
            Stack(
              children: [
                Container(
                  decoration: const BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.white,
                  ),
                  height: 185,
                  width: 185,
                ),
                AnimatedOpacity(
                  duration: const Duration(milliseconds: 1000),
                  opacity: _skygoalLogoOpacity,
                  child: Container(
                    padding: const EdgeInsets.only(top: 20),
                    child: Image.asset("assets/images/skygoal-logo.png"),
                    width: 164,
                  ),
                ),
              ],
            ),
            Stack(
              children: [
                AnimatedOpacity(
                  duration: const Duration(milliseconds: 2000),
                  opacity: _syjOpacity,
                  child: Container(
                    margin: const EdgeInsets.only(left: 40, top: 37),
                    height: 29,
                    width: 153,
                    child: Image.asset("assets/images/start-your-journey.png"),
                  ),
                ),
                // 用SlideTransition包裹FadeTransition,实现滑动+渐显的组合动画
                Container(
                  margin: const EdgeInsets.only(top: 5, left: 20),
                  child: SlideTransition(
                    position: _textSlideAnimation,
                    child: FadeTransition(
                      opacity: _textOpacityAnimation,
                      child: Text(
                        "SKYGOAL",
                        style: GoogleFonts.poppins(
                          fontSize: 30,
                          fontWeight: FontWeight.w800,
                          color: Colors.white,
                        ),
                        textAlign: TextAlign.center,
                      ),
                    ),
                  ),
                ),
              ],
            ),
            const Spacer(),
            const Text(
              "By Skygoal",
              style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold,
                fontSize: 13,
              ),
            ),
            Container(
              margin: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(10),
              ),
              height: 5,
              width: 134,
            )
          ],
        ),
      ),
    );
  }
}

关键修改说明:

  • 新增AnimationController统一管理动画的时长和运动曲线
  • 分别创建渐显、滑动两个动画对象,可自定义初始/结束值调整动画效果
  • 通过SlideTransition与FadeTransition的嵌套,让两个动画同时生效
  • 控制动画启动的延迟时间,保证与其他组件的动画节奏匹配
  • 在组件销毁时释放动画控制器,避免内存泄漏

内容的提问来源于stack exchange,提问作者Necromancer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:15:33