目 录CONTENT

文章目录

Flutter 全屏启动图Android 15 +上失效

ABin
2026-09-15 / 0 评论 / 0 点赞 / 1 阅读 / 0 字

起因

在用 Flutter 开发 App 时发现一个奇怪的现象:无论怎么配置,启动图始终没法做成全屏效果,系统总是显示"纯色背景 + 居中小图标"的样式。但手机里其他 App(比如闲鱼,同样是 Flutter 开发的)却能正常显示全屏启动图,一度让人怀疑是不是自己哪里配置漏了。

环境信息:

- 系统:Xiaomi HyperOS 2.0.209.0

- Android 版本:Android 15

排查过程

1. 先搞清楚 Android 官方的限制

从 Android 12(API 31)开始,Google 引入了官方的 SplashScreen API。这套新 API 的设计原则是:启动页只能是「纯色/渐变背景 + 居中小图标(约 240dp)+ 可选品牌图标」,**不允许**直接塞一张铺满全屏的位图作为系统级启动页。这是平台层面的硬性限制,跟用不用 Flutter 无关。

解决方案

第一步:退回老式配置,绕开新 API 的接管

找到 android/app/src/main/res/values-v31/styles.xml(如果有 values-night-v31/styles.xml 也一并处理),原本大概是这样:

<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">

    <item name="android:windowSplashScreenBackground">@color/bgColor</item>

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/launch_background</item>

</style>

改成和低版本values/styles.xml)保持一致,直接用传统的 windowBackground 全屏图,不声明任何新版属性:

<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">

    <item name="android:windowBackground">@drawable/launch_background</item>

</style>

launch_background.xml 用铺满全屏的图片即可,不要用「纯色背景 + 居中小图标」那种 layer-list 写法。

改完之后,在 HyperOS 上系统闪屏这一层就基本不会再显示了,或者显示的时间极短——因为系统只会在 Flutter 引擎渲染出第一帧之前有一个最低展示时间,无法完全消除,但可以压到几乎无感知。

### 第二步:把这"极短的一下"也藏起来

既然这一下无法彻底消除,更实用的做法是让它和你自己的全屏图**视觉上无缝衔接**:

1. 尽量缩短它的展示时长

- main() 里不要做重活(网络请求、大文件解析等),这些放到首页加载完成后异步执行:

   void main() {

       WidgetsFlutterBinding.ensureInitialized();

       runApp(MyApp()); // 尽快调用

     }

- 如果用了 flutter_native_splash 的 preserve/remove 机制,一定要在**首帧渲染完成后立刻** remove,不要因为等待网络请求而人为拖长:

FlutterNativeSplash.preserve(widgetsBinding: WidgetsFlutterBinding.instance);

     runApp(MyApp());

     // 在首屏 Widget build 完成后立刻调用

     FlutterNativeSplash.remove();

全屏图的停留时长,改用自己 Widget 里的 Future.delayed 之类逻辑控制,而不是靠拖延 remove 的时机实现。

- 用 release 包flutter build apk --release)测试速度,debug 包的 JIT 编译开销会造成误判。

- 第三方插件(推送、统计 SDK 等)的初始化尽量延后或异步执行,避免阻塞首帧渲染。

2. 让颜色过渡保持一致

系统这一层背景色设置成和全屏图主色调一致,图标区域用透明图或者极小的 Logo,避免出现"图标一闪又换成另一张图"的跳变感:

<item name="android:windowSplashScreenBackground">@color/splash_bg</item>

<item name="android:windowSplashScreenAnimatedIcon">@drawable/transparent_or_blank</item>

0

评论区