如何在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
相关产品推荐
相关产品推荐

