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

Flutter鉴权加载时显示flutter_native_splash解决启动页黑屏

GetX 结合 flutter_native_splash 无黑屏鉴权跳转实现方案

核心逻辑:将原生启动页的移除时机和鉴权状态强绑定,彻底移除自定义Flutter启动页,从根源规避首帧衔接黑屏问题,具体改造步骤如下:

1. 调整main函数初始化逻辑

删掉runApp之后立刻执行FlutterNativeSplash.remove()的代码,保留原生启动页直到鉴权流程完成:

void main() async {
  // 保留原有初始化绑定逻辑
  final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  // 保留原生启动页的逻辑不动
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  // 原有依赖注入逻辑不变,完成AuthService、AuthController等服务的注册
  await internalInitialized();
  // 直接启动应用,不要在此处移除原生启动页
  runApp(const MyApp());
}

2. 改造AuthController,绑定启动页移除时机

在鉴权状态的监听回调里处理原生启动页的移除,加标记位防止重复调用,仅在第一次拿到明确鉴权结果(已登录/未登录)时移除启动页:

enum AuthStatus { authenticationLoading, authenticated, unauthenticated }

class AuthController extends ConnectivityController {
  // 标记位:防止后续登录登出操作重复触发启动页移除
  bool _nativeSplashRemoved = false;
  final Rx<AuthStatus> authStatus = AuthStatus.authenticationLoading.obs;

  @override
  void onInit() {
    super.onInit();
    // 永久监听鉴权状态变化
    ever(authStatus, (currentStatus) {
      // 仅当鉴权出明确结果、且原生启动页未被移除时执行移除操作
      if (!_nativeSplashRemoved && currentStatus != AuthStatus.authenticationLoading) {
        FlutterNativeSplash.remove();
        _nativeSplashRemoved = true;
      }
    });
    // 原有自动登录逻辑保留,鉴权流程严格遵循状态流转
    getAuthenticatedUser();
  }

  // 原有getAuthenticatedUser、登录、登出方法逻辑保持不变:
  // 所有鉴权相关操作发起前,先将状态更新为authenticationLoading
  // 接口返回结果后,再根据鉴权结果更新为authenticated或unauthenticated
}

3. 简化MyApp的页面渲染逻辑

删掉原有的自定义SplashScreen组件,鉴权加载状态下原生启动页始终覆盖在Flutter渲染层之上,Flutter层只需要返回极简占位组件避免布局报错即可,不需要做任何加载UI:

class MyApp extends GetWidget<AuthController> {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      // 原有主题、路由、国际化等配置全部保留
      home: Obx(() {
        switch (controller.authStatus.value) {
          case AuthStatus.authenticated:
            return const HomeScreen();
          case AuthStatus.unauthenticated:
            return const SignInScreen();
          case AuthStatus.authenticationLoading:
            // 原生启动页覆盖期间,返回空占位即可
            return const SizedBox.shrink();
        }
      }),
    );
  }
}

注意事项

  • 所有涉及鉴权状态变更的逻辑必须严格遵守状态流转规则,禁止跳过loading状态直接更新终态,避免原生启动页提前或延后移除
  • 标记位_nativeSplashRemoved不可省略,后续手动登录、登出操作会再次将状态切为loading,此时原生启动页早已移除,重复调用remove方法会触发异常
  • 如果需要接入引导页、隐私协议弹窗等首屏逻辑,只需要在Obx的状态判断里增加对应分支即可,第一次鉴权完成后原生启动页就会移除,后续页面跳转走正常Flutter路由逻辑不受影响
  • 改造完成后首帧会直接渲染最终目标页面(首页/登录页),完全跳过Flutter层自定义启动页的渲染环节,不会出现原生页和Flutter页衔接的短暂黑屏问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:18:15