Flutter启动页问题:已登录用户延迟跳转首页的实现
Flutter Firebase启动页延迟跳转实现方案
问题描述
开发集成Firebase的Flutter应用,包含启动页(Splash Screen)。需求是:当用户已登录时,启动页需显示指定延迟时间后再跳转至首页;未登录则跳转登录页。之前使用命名路由,现在改为直接返回页面的方式,但尝试initState中使用Future.delayed、以及第二种代码片段的实现均未达到预期效果。
现有代码问题分析
- 初始代码问题:
StreamBuilder直接返回Home或LogIn页面,Firebase auth状态就绪后会立即替换启动页UI,导致启动页无法正常显示。 - 第二种代码问题:
- 在
StreamBuilder的builder方法中调用Future.delayed,每次UI重建都会重复触发延迟逻辑,造成资源浪费。 - 修改
delayCompleted变量时未调用setState,UI不会感知状态变化,始终显示CircularProgressIndicator。 - 逻辑上未将Hive初始化、延迟等待、auth状态监听三者结合,导致流程混乱。
- 在
正确实现方案
核心思路:在initState中完成Hive初始化,等待指定延迟时间,同时获取Firebase auth状态,待所有准备工作完成后,通过导航跳转至对应页面,确保启动页UI完整显示至延迟结束。
修改后的完整代码
import 'package:carecraft/ui/screens/login.dart'; import 'package:carecraft/ui/theme.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/adapters.dart'; import 'home.dart'; class Splash extends StatefulWidget { const Splash({super.key}); @override State<Splash> createState() => _SplashState(); } class _SplashState extends State<Splash> { @override void initState() { super.initState(); _initializeAndNavigate(); } Future<void> _initializeAndNavigate() async { // 1. 初始化Hive await Hive.initFlutter(); Hive.registerAdapter<TimeOfDay>(TimeOfDayAdapter()); await Hive.openBox<TimeOfDay>('drug'); // 2. 等待指定延迟时间(可根据需求调整) await Future.delayed(const Duration(seconds: 3, milliseconds: 500)); // 3. 获取当前用户登录状态 final user = FirebaseAuth.instance.currentUser; // 4. 跳转至对应页面 if (!mounted) return; // 防止页面已销毁时导航报错 Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => user != null ? const Home() : const LogIn(), ), ); } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [bleuTresTresClair, bleuTresClair, bleuClair, bleu], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: Center( child: Stack( alignment: Alignment.center, children: [ Positioned( top: 0, child: Image.asset( 'assets/carecraft.png', height: MediaQuery.of(context).size.width * 0.9, width: MediaQuery.of(context).size.height * 0.9, ), ), Positioned( top: MediaQuery.of(context).size.height * 0.41, left: MediaQuery.of(context).size.width * 0.45, child: Image.asset( 'assets/androidinsat.png', height: MediaQuery.of(context).size.width * 0.23, width: MediaQuery.of(context).size.height * 0.23, ), ), Positioned( top: MediaQuery.of(context).size.height * 0.45, child: Image.asset( 'assets/splash.png', height: MediaQuery.of(context).size.width * 1.1, width: MediaQuery.of(context).size.height * 1.1, ), ), // 可选:显示加载指示器,告知用户正在准备 const CircularProgressIndicator(color: Colors.white), ], ), ), ), ); } }
方案说明
- 将所有初始化和导航逻辑放在
_initializeAndNavigate异步方法中,避免阻塞UI线程。 - 先完成Hive初始化,再等待延迟,确保必要的本地存储准备完成后再跳转。
- 使用
Navigator.pushReplacement替换启动页,避免用户返回时回到启动页。 - 添加
mounted判断,防止页面已销毁时执行导航操作引发错误。 - 启动页UI保持完整显示,直到所有准备工作完成后才跳转,满足延迟显示需求。
内容的提问来源于stack exchange,提问作者ESvi3
相关产品推荐
相关产品推荐

