1.要求狀態列透明,我們的內容佈局延伸到系統狀態列,就是人們口中說的沉浸式狀態列:
Android 5.0 及其以後版本:設定屬性 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
使得我們的內容佈局可以延伸到系統狀態列,然後直接使用方法 setStatusBarColor()
把系統狀態列設定成透明就好了。
Android 4.4 ~ Android 5.0 :新增了屬性 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
可以讓狀態列變成透明,並且使我們們的內容佈局延伸到系統狀態列。這個屬性雖然也可以在 Android 5.0 及其以後版本的手機上使用,但是效果不是我們想要的。
在 Android 4.4 之前是不支援透明狀態列
需要注意的一點是在設定透明狀態列的情況下,是需要我們的內容佈局延伸到狀態列的,因此這個時候使用 fitSystemWindows
這個屬性是沒有意義的,只會使得出現各種奇葩的效果。
2.狀態列顏色和我們佈局顏色搭配
其實在有的時候,我們是不需要把我們的內容佈局延伸到系統狀態列的,只是需要系統狀態列和我們的內容佈局的顏色搭配起來。
**Android 5.0 及其以後版本:**直接通過 setStatusBarColor()
或者 修改colorPrimaryDark
對應的顏色,把系統狀態列顏色設定成搭配的顏色就可以了
**Android 4.4 ~ Android 5.0:**這個版本其實是不允許直接修改狀態列的顏色的,只不過我們利用了一種巧妙的方法,感覺是修改了狀態列的顏色而已。通過 getWindow().addFlags(WindowManager.LayoutParams.FALG_TRANSLUCENT_STATUS)
是狀態列透明,並且我們的佈局也會延伸到狀態列,給我們的內容佈局設定一個 padding,給這個 padding 設定一個合適的顏色來充當系統狀態列的顏色就可以了。
Android 4.4 之前是不支援修改的
其實狀態列的適配無外乎這兩點了,注意一定要針對不同的 Android 版本使用不同的方法,不可亂用,不可混用,不然會有各種奇葩效果!
效果圖
Android 4.4 以前
狀態列永遠是黑底白字,沒有方法改變。上面的所有的方法也是不適用的。
Android 4.4~Android 5.0
Android 4.4 引入了 FLAG_TRANSLUCENT_STATUS 這種模式,使用這種模式可以使內容佈局佔據狀態列,效果:
android:fitsSystemWindows = "true" 屬性
可以理解為給所使用的佈局設定了狀態列大小的 padding。只會作用於 Toolbar 和 根佈局。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/main_green_00b661"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tb"
app:title="@string/activity_status_bar"
app:titleTextColor="@android:color/white"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@color/colorAccent">
</android.support.v7.widget.Toolbar>-->
<TextView
android:fitsSystemWindows="true"
android:background="@color/main_green_00b661"
android:layout_width="match_parent"
android:layout_height="1dp"
android:text="11"
android:textColor="#000"/>
<ImageView
android:contentDescription="@string/text_input"
android:id="@+id/iv"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:src="@mipmap/imga"/>
<TextView
android:background="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="11"
android:textColor="#000"/>
</LinearLayout>
比如,佈局是這樣的,fitsSystemWindows 只有在根佈局 LinearLayout 或者 ToolBar 上有用,在別的 View 上使用是沒有效果的。
複製程式碼
LinearLayout 使用 fitsSystemWindows
ToolBar 設定 fitsSystemWindows 效果
可以看到效果了。其實就是相當於給佈局設定了 padding top(高度相當於系統狀態列的高度),但是考慮到相容性的問題,如果你直接在佈局中設定 paddingtop 而不是通過 FitsSystemWindows
這個屬性,那麼在 Android 4.4 以下的手機上執行的話,那麼效果就很糟糕了,因為 Android 4.4 以下的手機,系統狀態列都是始終存在的,也就是說,這樣始終比 Android 4.4 以上系統的手機佈局多一塊 padding ,因為這一塊 padding 沒法在系統狀態列上。但是使用 fitsSystemWindo 就會完美適配了,因為這個屬性在 Android 4.4 以下的系統上是不起作用的。注意在使用 fitsSystemWindow 的時候,顏色問題,不同的手機系統,可能會造成延伸到狀態列的那一塊顏色不同,理論上顏色應該和根佈局的顏色一樣。
Android 5.0
到了 Android 5.0 關於狀態列又發生了變化,新增了直接對狀態列的操作,直接改變狀態列顏色,這一點在之前版本是沒有的,Android 4.4 雖然可以實現改變狀態列顏色的效果,但其實實際上是將我們的佈局佔據了狀態列,然後狀態列是透明的。其實顏色還是我們佈局的顏色。
對 Android 5.0 的採取
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); (和上面對 Android 4.4 的方法是一樣的);
複製程式碼
效果圖:
Android 6.0
在 Android 6.0 新增了可以更改狀態列字型顏色的方法,別的都是和 Android 5.0 一樣的。
狀態列字型顏色預設是白色。可以修改為黑色。
方法:getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
// 方法
/*
* 當 insets 檢視插入,window 已經更改了,檢視層次結構呼叫。允許它調整內容來適應這些視窗。這個 insets 會告訴我們 status bar、input method 和其他系統 window 的空間。
通常情況下我們是不需要處理此功能的,因為應用程式的預設視窗修飾會將其應用於視窗內容。如果我們使用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 或者 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 的時候,則需要處理這個函式了,這個時候如果我們不處理,我們的檢視內容就會預設放在系統檢視的下面。如果我們希望系統檢視不覆蓋UI的某些部分,則可以在檢視層次結構中使用此方法。
預設情況下,只是將 insets(將 insets 設定為 0 )做為 View 的 padding。並且返回true。預設情況下,此行為是關閉的,但是可以通過 setFitsSystemWindows(boolean)啟用。
此功能在層次結構中的遍歷是深度優先的。 相同的內容insets物件沿著層次結構向下傳播,因此對其所做的任何更改都將被所有後續檢視看到(包括層次結構中的上層檢視,因為這是深度優先遍歷)。 返回true的第一個檢視將中止整個遍歷。
*/
fitSystemWindows(Rect insets);
複製程式碼