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

Activity沉浸式模式异常:返回主Fragment后布局无法全屏适配

问题描述
  • Activity包含多个Fragment,主Fragment允许屏幕旋转,其他Fragment禁用旋转
  • 应用启动后主Fragment可正常以沉浸式全屏显示,切换到其他Fragment时仍能保持沉浸式状态
  • 返回主Fragment后,导航栏虽已隐藏,但布局未适配全屏,BottomNavigationView无法覆盖原导航栏所在的底部区域(异常表现:底部留空,布局未占满屏幕)

现有实现代码

Activity中的setFullScreen()方法

fun setFullScreen() {
    this.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
    val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
    windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}

Fragment的onResume()调用逻辑

override fun onResume() {
    super.onResume()
    val activity = activity as MainActivity
    activity.setFullScreen()
}
解决方案

从窗口布局配置、Insets适配、状态同步三方面调整,确保布局能正确延伸到系统栏隐藏后的区域:

1. 让Activity布局延伸到系统栏区域

在Activity的onCreate()中添加窗口配置,允许内容布局覆盖系统栏所在的空间:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 核心配置:关闭系统栏自动适配,让布局延伸到系统栏区域
    WindowCompat.setDecorFitsSystemWindows(window, false)
    setContentView(R.layout.activity_main)
    // 其他初始化代码...
}

2. 优化setFullScreen()方法,强制布局重绘

更新方法,确保设置旋转方向和隐藏系统栏后,触发布局重新计算,适配当前全屏状态:

fun setFullScreen() {
    this.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
    val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
    windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
    
    // 强制窗口重新计算布局,同步Insets状态
    window.decorView.requestLayout()
}

3. 适配BottomNavigationView的布局参数

若BottomNavigationView仍无法贴到屏幕底部,添加Insets监听,清除底部边距:

// 在Activity或主Fragment中初始化BottomNavigationView时设置
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
ViewCompat.setOnApplyWindowInsetsListener(bottomNav) { view, insets ->
    val params = view.layoutParams as ViewGroup.MarginLayoutParams
    // 清除底部margin,让控件贴到屏幕最底部
    params.bottomMargin = 0
    view.layoutParams = params
    // 消费Insets,避免影响其他布局
    insets
}

4. 同步非主Fragment的旋转状态

在非主Fragment的onResume()中,除了调用全屏方法,还要设置固定旋转方向:

override fun onResume() {
    super.onResume()
    val activity = activity as MainActivity
    activity.setFullScreen()
    // 根据需求设置固定方向,比如竖屏
    activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:55:01