android:fitsSystemWindows屬性可以實現狀態欄沉浸式效果,但是xml中需要配合CoordinatorLayout處理,但是在CoordinatorLayout中的組件會自動顯示在狀態欄下面,如果希望設置一張圖片,填滿狀態欄,那么可以配合CollapsingToolbarLayout、DrawerLayout等進行處理
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff66ff"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/bg"
android:fitsSystemWindows="true"
/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
這里我們在ImageView的外面又包裹了一層CollapsingToolbarLayout,并且給CollapsingToolbarLayout也設置了android:fitsSystemWindows屬性,這樣CollapsingToolbarLayout就可以將內容延申到狀態欄區域了。
給ImageView同樣設置了android:fitsSystemWindows屬性,如此一來,就可以讓圖片顯示在狀態欄的背后了。
如果采用FrameLayout布局,那么為了實現沉浸式狀態欄的效果,我們手動在MainActivity當中調用setSystemUiVisibility()函數,來將FrameLayout的內容延伸到狀態欄區域:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
window.statusBarColor = Color.TRANSPARENT
val frameLayout = findViewById<FrameLayout>(R.id.root_layout)
frameLayout.systemUiVisibility = (SYSTEM_UI_FLAG_LAYOUT_STABLE
or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
}
這樣xml中的組件會直接占用狀態欄空間,如果需要設置某些組件在狀態欄下顯示,那么可以借助setOnApplyWindowInsetsListener()函數去監聽WindowInsets發生變化的事件,當有監聽到發生變化時,我們可以讀取頂部Insets的大小,然后對控件進行相應距離的偏移。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
window.statusBarColor = Color.TRANSPARENT
val frameLayout = findViewById<FrameLayout>(R.id.root_layout)
frameLayout.systemUiVisibility = (SYSTEM_UI_FLAG_LAYOUT_STABLE
or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
val button = findViewById<Button>(R.id.button)
ViewCompat.setOnApplyWindowInsetsListener(button) { view, insets ->
val params = view.layoutParams as FrameLayout.LayoutParams
params.topMargin = insets.systemWindowInsetTop
insets
}
}
}
參考鏈接:https://blog.csdn.net/guolin_blog/article/details/123023395