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

Android使用Splash Screen Api+导航组件遇闪屏问题求解决方案

问题解决思路

一、根据Fragment ViewModel状态控制闪屏显示

你当前代码直接用Fragment的homeViewModel会有问题——闪屏初始化时Fragment还没创建,ViewModel也没实例化,而且Fragment的ViewModel生命周期绑定到Fragment,不适合用来控制Activity级的闪屏。给你两个可行方案:

方案1:把加载逻辑移到Activity级ViewModel

  • 新建一个Activity级的LaunchViewModel,专门管理启动阶段的加载状态,要么把首页数据加载逻辑迁到这里,要么让它协调Fragment ViewModel的状态:
// 1. 定义启动状态ViewModel
class LaunchViewModel : ViewModel() {
    private val _launchState = MutableLiveData<LaunchState>()
    val launchState: LiveData<LaunchState> = _launchState

    // 监听Fragment的ViewModel状态,转换为启动状态
    fun bindHomeState(homeViewModel: HomeViewModel) {
        homeViewModel.homeCollectionState.observeForever { state ->
            _launchState.value = when (state) {
                is HomeCollectionState.Loading, is HomeCollectionState.Idle -> LaunchState.Loading
                else -> LaunchState.Ready
            }
        }
    }
}

sealed class LaunchState {
    object Loading : LaunchState()
    object Ready : LaunchState()
}

// 2. 在MainActivity中使用
class MainActivity : AppCompatActivity() {
    private lateinit var launchViewModel: LaunchViewModel
    private lateinit var homeViewModel: HomeViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        // 第一步必须调用installSplashScreen,不能延后
        val splashScreen = installSplashScreen()

        super.onCreate(savedInstanceState)
        launchViewModel = ViewModelProvider(this)[LaunchViewModel::class.java]
        // 初始化HomeViewModel(如果是Navigation管理的Fragment,也可以通过NavHost获取)
        homeViewModel = ViewModelProvider(this)[HomeViewModel::class.java]
        launchViewModel.bindHomeState(homeViewModel)

        // 设置闪屏保持条件:只要还在加载/空闲状态就保持显示
        splashScreen.setKeepOnScreenCondition {
            launchViewModel.launchState.value == LaunchState.Loading
        }

        setContentView(R.layout.activity_main)
        // 初始化Navigation等后续逻辑
    }
}

方案2:用LiveData跨组件传递状态

如果不想迁移逻辑,可以让Fragment的ViewModel暴露一个LiveData,然后在MainActivity中通过Activity级的ViewModel作为中介来观察这个状态。不过要注意,必须确保Fragment创建后状态能正确传递,避免闪屏提前消失。

二、必须在MainActivity调用installSplashScreen的原因

这是Splash Screen API的硬性要求:必须在super.onCreate(savedInstanceState)之后、setContentView()之前调用installSplashScreen(),否则系统会因为闪屏过渡的初始化流程缺失而崩溃。

闪屏是Activity层面的系统组件,负责衔接系统启动闪屏和应用内容,所以只能在宿主Activity(也就是你的MainActivity)中调用,不能放到Fragment里。你完全不用放弃这个API,只要遵守调用时机就行。

总结

不用自定义Fragment闪屏,只要把闪屏的状态控制逻辑放到Activity级的ViewModel中,同时按要求在MainActivity的onCreate开头调用installSplashScreen(),就能解决你遇到的两个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:42:29