一、前言
Android推崇Material Design,其中一個(gè)亮點(diǎn)是沉浸式狀態(tài)欄。該形式狀態(tài)欄從Android 4.4(v19)開始得到原生支持。這次我們在應(yīng)用中簡單實(shí)現(xiàn)一下。

二、依賴
在build.gradle(Module:app)中添加依賴項(xiàng),版本根據(jù)Android Studio提示使用最新即可,修改完成記得同步一下。
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:support-v4:25.1.0'
compile 'com.android.support:design:25.1.0'
三、樣式
在res/values/styles.xml新建自定義主題BaseAppTheme,其父主題是Theme.AppCompat.Light.NoActionBar,然后再創(chuàng)建一個(gè)BarTheme繼承BaseAppTheme。
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="BarTheme" parent="BaseAppTheme" />
在res文件夾下新建一個(gè)名為values-v19的文件夾。

在res/values-v19/新建一個(gè)styles.xml,名字在IDE里面顯示為styles.xml(v19)。這個(gè)樣式里面只需編寫BarTheme繼承BaseAppTheme。被繼承BaseAppTheme是上一個(gè)styles.xml設(shè)置好的,會自動引用過來。
<style name="BarTheme" parent="BaseAppTheme">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:textColorPrimary">#FFFFFF</item>
</style>
三個(gè)參數(shù)分別作用:
- 1.半透明狀態(tài)欄設(shè)置為啟用,沒有的話就不會有沉浸式狀態(tài)欄效果。這個(gè)參數(shù)從v19開始引入,之前版本里會提示不支持。
- 2.為
NavigationView提供半透明支持,通常是左抽屜。沒有抽屜不需要這個(gè)參數(shù)。 - 3.用來改變Toolbar標(biāo)題文字的樣色。
四、自定義ToolBar
在activity_main.xml自定義ToolBar,background改變ToolBar的顏色。fitsSystemWindows是要系統(tǒng)把狀態(tài)欄的動態(tài)和ToolBar相適應(yīng),狀態(tài)欄的顏色會跟隨ToolBar的融為一體。
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0084eb"
android:fitsSystemWindows="true"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
fitSystemWindows要點(diǎn):
- 只把
fitSystemWindows放在Layout的根布局上,狀態(tài)欄就和根布局背景顏色一樣,不知道能不能說就是透明。 - 同時(shí)在根布局和
ToolBar上設(shè)置fitSystemWindows,效果跟隨根布局,忽略ToolBar。 - ToolBar的
layout_height不能用?attr/actionBarSize,只能wrap_content。之前就是因?yàn)檫@個(gè)原因一直沒有成功。
剩下就是在MainActivity.java里面實(shí)現(xiàn)了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
}
最后在AndroidManifest.xml里面把Main_Activity的主題換成我們自定義的BarTheme樣式。
android:theme="@style/BarTheme"
因?yàn)槭褂闷渌黝}時(shí)系統(tǒng)會自行添加一個(gè)ToolBar。如果我們又自定義一個(gè),相當(dāng)于有兩個(gè)ToolBar,兩個(gè)ToolBar的沖突會在編譯時(shí)拋出:
01-11 19:16:01.596 19257-19257/com.phantomvk.statusbar E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.phantomvk.statusbar, PID: 19257
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.phantomvk.statusbar/com.phantomvk.statusbar.MainActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
....
....
所以我們先把主題設(shè)置為NoActionBar,才在onCreate中setSupportActionBar(toolbar)里加入自定義的。
五、模擬器和物理機(jī)差別
我注意到Android5.0上物理機(jī)和虛擬機(jī)顯示狀態(tài)欄的效果不一樣。網(wǎng)上也有一些開發(fā)者討論了這個(gè)情況。因?yàn)槭稚蟿偤糜蠥ndroid5.0的三星S4,所以順手測試了一下。
在Android的模擬器中,狀態(tài)欄的顏色是半透明,且顏色更深。

在S4上,就是完全透明,和ToolBar的顏色完全一致。

因?yàn)楝F(xiàn)在的手機(jī)系統(tǒng)都經(jīng)過定制,甚至很多事深度定制。在模擬器上測試的結(jié)果,在物理機(jī)上測試未必一樣。如果在主題樣式顯示差異有什么疑問,請務(wù)必要用多款物理機(jī)測試。