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

如何在Flutter启动页(Splash Screen)动画后添加淡入过渡动画

问题描述

我正在开发一款应用,决定添加启动页(Splash Screen)动画作为应用启动效果。动画本身表现完美,但动画结束后出现了问题:页面跳转时元素突然就位,导致应用看起来卡顿。我希望通过淡入过渡到下一个页面,让整体效果更流畅。

相关代码

main.dart

void main() {
  runApp(
    MaterialApp(
      theme: theme,
      routes: {
        '/': (context) => Splash(),
        '/login': (context) => LoginScreen(),
      },
    ),
  );
}

splash.dart

以下是启动页的全部功能代码

class Splash extends StatefulWidget {
  const Splash({super.key});


  @override
  State<Splash> createState() => _SplashState();
}

class _SplashState extends State<Splash> with RouteAware{
  var isVisible = false;

  void initState() {
    super.initState();
    startTimer();
  }

  startTimer(){
    var duration = Duration(milliseconds: 3340);
    return Timer(duration, route);
  }

  route(){
    Navigator.pushReplacementNamed(context, '/login');
    print(ModalRoute.of(context)?.settings.name);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 0, 0, 0),
      body: content(),
    );
  }

  Widget content() {
    return Center(
      child: Container(
        child: Lottie.asset('assets/images/splash.json'),
      ),
    );
  }
}

Login.dart

经过调研,我尝试用AnimatedOpacity包裹LoginForm,但由于找不到触发方式,未能生效。

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> with RouteAware{
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Center(
        child: Container(
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              colors: [
                Color.fromARGB(255, 50, 50, 50),
                Color.fromARGB(255, 0, 0, 0)
              ],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
          child: const LoginForm(),
        ),
      ),
    );
  }
}
解决方案

方法1:自定义路由过渡(推荐)

直接修改splash.dart中的route方法,使用PageRouteBuilder实现淡入过渡,无需改动LoginScreen代码:

route(){
  Navigator.pushReplacement(
    context,
    PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) => LoginScreen(),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return FadeTransition(
          opacity: animation.drive(Tween(begin: 0.0, end: 1.0)),
          child: child,
        );
      },
      transitionDuration: Duration(milliseconds: 500), // 可根据需求调整过渡时长
    ),
  );
}

此方式让登录页从完全透明平滑过渡到完全显示,解决跳转时的突兀感。

方法2:在LoginScreen中实现AnimatedOpacity淡入

若坚持使用AnimatedOpacity,只需在LoginScreen的初始化阶段触发透明度变化:
修改Login.dart代码如下:

class _LoginScreenState extends State<LoginScreen> with RouteAware{
  double _opacity = 0.0;

  @override
  void initState() {
    super.initState();
    // 延迟触发淡入,避免与启动页动画冲突
    Future.delayed(Duration(milliseconds: 100), () {
      setState(() {
        _opacity = 1.0;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AnimatedOpacity(
          opacity: _opacity,
          duration: Duration(milliseconds: 500),
          child: Container(
            decoration: const BoxDecoration(
              gradient: LinearGradient(
                colors: [
                  Color.fromARGB(255, 50, 50, 50),
                  Color.fromARGB(255, 0, 0, 0)
                ],
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
              ),
            ),
            child: const LoginForm(),
          ),
        ),
      ),
    );
  }
}

页面初始化后,通过延迟将透明度从0切换到1,实现登录页的平滑淡入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:44:51