什么是StatusBar
首先,谷歌官方的解釋是,用于顯示通知,傳達設(shè)備狀態(tài)的屏幕區(qū)域,與應(yīng)用同時顯示。而為了能夠使應(yīng)用顯示沉浸式的內(nèi)容(如電影圖片等),官方賦予了應(yīng)用對狀態(tài)欄在一定程度上的控制能力,如應(yīng)用可以調(diào)暗或者隱藏狀態(tài)欄、沉浸式交互控制狀態(tài)欄。
在實際項目開發(fā)中,通常情況下,我們對狀態(tài)欄的玩法有以下幾種
- 隱藏或者顯示狀態(tài)欄
- 狀態(tài)欄著色
- 應(yīng)用內(nèi)容延伸到狀態(tài)欄底下
- 設(shè)置狀態(tài)欄文字為黑色
官方推薦的StatusBar用法
谷歌官方建議,在設(shè)計應(yīng)用時最好遵循標(biāo)準(zhǔn)的Android界面準(zhǔn)則和使用模式。而Android賦予開發(fā)者控制StatusBar的能力的初衷,是為了在某些情況下(例如電影和圖片)能夠沉浸式的顯示應(yīng)用內(nèi)容,減少狀態(tài)欄對用戶的干擾,以便為用戶帶來更好的沉浸式體驗。所以官方推薦以下幾種對StatusBar的用法
1.調(diào)暗StatusBar
效果如下圖,實現(xiàn)方式也很簡單。此方式僅可以在Android4.0(API14)以上使用
// This example uses decor view, but you can use any visible view.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);
當(dāng)輕觸狀態(tài)欄,此標(biāo)記即被清除,如果希望再次調(diào)暗狀態(tài)欄,需要重置該標(biāo)記
- 隱藏狀態(tài)欄
在Android4.0版本以下,有兩種方式可以實現(xiàn)
- 設(shè)置Activity的主題背景
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
- 通過編程方式設(shè)置 WindowManager 標(biāo)志
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
當(dāng)設(shè)置 WindowManager 標(biāo)志時(無論是通過 Activity 主題背景還是通過編程方式),這些標(biāo)志將保持有效,直到應(yīng)用將它們清除為止。
Android4.1以及更高版本中
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
離開該視圖會導(dǎo)致系統(tǒng)清除使用 setSystemUiVisibility() 設(shè)置的標(biāo)志
- 應(yīng)用內(nèi)容顯示在狀態(tài)欄下面
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
- 全屏模式,全屏模式下StatusBar都是隱藏的,所不同在于用戶讓StatusBar重新顯示的方式不同
- Lean back 模式,此模式適用于用戶不會和屏幕進行大量的交互,例如在觀看視頻時候。只需要點擊屏幕任意位置,即可調(diào)出狀態(tài)欄
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
- Immersive 模式,適用于用戶需要和屏幕進行大量的交互,例如看圖片玩游戲,只需要從狀態(tài)欄一側(cè)滑動,就可以調(diào)出狀態(tài)欄
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE);
- Sticky immersive 模式,此模式邊緣滑動事件依然可以傳遞給應(yīng)用,同時狀態(tài)欄會以半透明的方式出現(xiàn),并且在無互動幾秒或者用戶在狀態(tài)欄之外的任何位置輕觸,狀態(tài)欄會自動消失。
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- 顯示狀態(tài)欄
getWindow().getDecorView().setSystemUiVisibility(0);
同時為了防止布局隨著狀態(tài)欄的隱藏和顯示調(diào)整大小,最好加上
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
StatusBar在項目中常見用法的實現(xiàn)方式
通過以上官方推薦的幾種常見用法,以及這些用法的組合,基本可以滿足我們?nèi)粘m椖恐兴枰母鞣N需求。實現(xiàn)方式和思路也多種多樣,下面列舉一些常見的實現(xiàn)方式
隱藏和顯示狀態(tài)欄
如上官方推薦方式
狀態(tài)欄著色
- 方案一
getWindow().setStatusBarColor(ResourceUtils.getColor(R.color.hotnews_app_theme_color));
- 方案二,將狀態(tài)欄設(shè)置為透明,然后添加一個與狀態(tài)欄等高的View,相當(dāng)于用此View來代替狀態(tài)欄。而這個view是我們可以隨意控制的。
沉浸式顯示(即應(yīng)用內(nèi)容填充在狀態(tài)欄下方)
- 方案一,效果如下
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- 方案二,將應(yīng)用內(nèi)容延伸至StatusBar下方,同時設(shè)置statusBar顏色為透明,效果如下
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
- 方案三,思路同上
View decorView = getWindow().getDecorView();
decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
WindowInsets defaultInsets = v.onApplyWindowInsets(insets);
return defaultInsets.replaceSystemWindowInsets(
defaultInsets.getSystemWindowInsetLeft(),
0,
defaultInsets.getSystemWindowInsetRight(),
defaultInsets.getSystemWindowInsetBottom());
}
});
ViewCompat.requestApplyInsets(decorView);
getWindow().setStatusBarColor(Color.TRANSPARENT);
設(shè)置狀態(tài)欄文字為黑色
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
總結(jié)
以上便是StatusBar的基本用法,在項目開發(fā)需求中,我們可以根據(jù)具體的需求,通過對以上各種實現(xiàn)方式的自由組合,以及靈活的思路,實現(xiàn)相應(yīng)的功能。