用经典的 DrawerLayout 和 NavigationView 的遮挡为例: 不说废话,解决方案如下:
1. 使用 fitsSystemWindows 属性
在你的 DrawerLayout 中设置 android:fitsSystemWindows="true"。这可以让 DrawerLayout 自动处理系统窗口(包括状态栏):
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Main content layout -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- content -->
</FrameLayout>
<!-- Navigation view -->
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<!-- navigation menu -->
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
2. 设置 Window Flags
在 onCreate 方法中,通过代码来设置系统 UI 可见性:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 设置全屏布局模式
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// 如果你希望透明状态栏
window.statusBarColor = Color.TRANSPARENT
}
3. 使用 WindowInsetsController (API 30+)
在 Android 11 (API 30) 及以上,你可以使用 WindowInsetsController 来处理系统窗口:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val windowInsetsController = window.insetsController
if (windowInsetsController != null) {
windowInsetsController.hide(WindowInsets.Type.statusBars())
windowInsetsController.systemBarsBehavior =
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
4. 设置 DrawerLayout 的 ClipToPadding
你可以通过代码设置 DrawerLayout 的 clipToPadding 属性为 false,这将允许内容在状态栏下显示:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)
drawerLayout.clipToPadding = false
}
5. 使用 ViewCompat 进行窗口插入处理
使用 ViewCompat 来请求调整 DrawerLayout 的窗口插入:
ViewCompat.setOnApplyWindowInsetsListener(drawerLayout) { view, insets ->
val insetsCompat = ViewCompat.onApplyWindowInsets(view, insets)
insetsCompat.consumeSystemWindowInsets()
}