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
相关产品推荐
相关产品推荐

