Android 沉浸式狀態(tài)欄

沉浸式含義

首先先明確一點沉浸式狀態(tài)欄的說法并不準確,沉浸式是Android4.4推出的一種模式,可以使顯示系統(tǒng)消息的狀態(tài)欄(Status Bar)與最下方顯示虛擬按鍵的底部導航欄(Navigation Bar)被隱藏掉。
在谷歌開發(fā)文檔中對沉浸式的描述是:“系統(tǒng) UI 保持隱藏狀態(tài),即使在用戶與您的應用或游戲交互時 - 您可以從屏幕上的任何位置(甚至在系統(tǒng)欄占據(jù)的其他位置)捕獲觸摸事件。這是您在應用或游戲中創(chuàng)建更大、更加豐富和更加沉浸式的 UI 并減少視覺分散的絕佳方式。”

Android4.4沉浸式API

1、沉浸式全屏模式
setSystemUiVisibility (int visibility)
看了下標記多達十來個,以下截取部分常用標記:

SYSTEM_UI_FLAG_FULLSCREEN(WindowManager.LayoutParams.FLAG_FULLSCREEN)//隱藏狀態(tài)欄,手指在屏幕頂部往下拖動,狀態(tài)欄會再次出現(xiàn)且不會消失
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //配合SYSTEM_UI_FLAG_FULLSCREEN使用狀態(tài)欄出現(xiàn)時,不會擠壓activty的高度,隱藏狀態(tài)欄,手指在屏幕頂部往下拖動,狀態(tài)欄會再次出現(xiàn)且不會消失

SYSTEM_UI_FLAG_IMMERSIVE// 這個標記僅與SYSTEM_UI_FLAG_HIDE_NAVIGATION配合使用,在全屏模式下在狀態(tài)欄區(qū)域滑動會重新顯示狀態(tài)欄
SYSTEM_UI_FLAG_IMMERSIVE_STICKY//在全屏模式下在狀態(tài)欄區(qū)域滑動會重新顯示透明式狀態(tài)欄,一會后會重新隱藏,與SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION配合產(chǎn)生效果。

SYSTEM_UI_FLAG_HIDE_NAVIGATION//隱藏導航欄,手指在導航欄滑動,導航欄會再次出現(xiàn)且不會消失
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION//配合SYSTEM_UI_FLAG_HIDE_NAVIGATION使用導航欄會出現(xiàn)時,不會擠壓activty的高度,隱藏導航欄會,手指在導航欄滑動,導航欄會再次出現(xiàn)且不會消失

SYSTEM_UI_FLAG_LAYOUT_STABLE //保持內(nèi)容主體位置不變,不隨著Systembar的隱藏顯示而偏移

2、透明系統(tǒng)狀態(tài)欄
新增兩個新主題背景Theme_Holo_NoActionBar、Theme_Holo_Light_NoActionBar,如果需要不應被系統(tǒng)狀態(tài)欄覆蓋的布局部分則應該啟用fitsSystemWindows。
對于fitsSystemWindows,官方的說法是“布爾內(nèi)部屬性,用于根據(jù)系統(tǒng)窗口(如狀態(tài)欄)調(diào)整視圖布局。如果為true,則調(diào)整此視圖的填充以為系統(tǒng)窗口留出空間。僅在此視圖位于非嵌入活動中時才會生效?!蹦J值為false

如果需要創(chuàng)建自定義主題,可將其中一個設置為父主題背景或者在樣式中添加windowTranslucentNavigation(對應WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)與windowTranslucentStatus(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)

Android5.0沉浸式API

在Android5.0開始官方提供了android:statusBarColor (對應方法為 setStatusBarColor),且窗口必須使用FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS繪制系統(tǒng)欄背景
不得設置FLAG_TRANSLUCENT_STATUS。

Android9.0全面屏API

Android9.0開始增加對全全面屏的適配
具體增加以下三種標記

LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT(只有當DisplayCutout完全包含在系統(tǒng)狀態(tài)欄中時,才允許窗口延伸到DisplayCutout區(qū)域顯示)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES(該窗口始終允許延伸到屏幕短邊上的DisplayCutout區(qū)域)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER(該窗口決不允許與DisplayCutout區(qū)域重疊)

android9.0全面屏沉浸式代碼

        getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().setAttributes(lp);
        window.setStatusBarColor(Color.TRANSPARENT);

沉浸式分析

以下沉浸式實現(xiàn)以兩種情況做分析分別式圖片沉浸式和ActionBar沉浸式

圖片沉浸式(隱藏狀態(tài)欄圖標)

圖片沉浸式的應用相對較多最常見的例如splash頁面

Android 4.4

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);    
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
getWindow().getDecorView().setSystemUiVisibility(system_ui_flag_fullscreen|system_ui_flag_hide_navigation);
image.png

Android 5.0

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);    
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
getWindow().getDecorView().setSystemUiVisibility(system_ui_flag_fullscreen|system_ui_flag_hide_navigation);

同Android4.4

Android 9.0

window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(lp);
getWindow().getDecorView().setSystemUiVisibility(system_ui_flag_fullscreen|system_ui_flag_hide_navigation);

Android9.0提供新標記(LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)來適配全面屏、劉海屏等異形屏。

ActionBar沉浸式(顯示狀態(tài)欄圖標)

Android 4.4

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);                
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

使用如上代碼 所呈現(xiàn)的UI樣式為:


image.png

可以看出actionBar占住了statusBar的位置,如果statusBar上有圖標可能會與actionBar重疊,由于當前是在Android4.4上執(zhí)行的demo,不能使用
setStatusBarColor方法。所以我們可以在actionBar增加一個與statusBar一摸一樣的View,使之呈現(xiàn)出沉浸式感覺。
具體代碼:

    /**
     * 創(chuàng)建一個與statusBar一樣的View
     * @param color View顏色
     */
    private View createStatusBarView(Activity activity, int color) {
        // 繪制一個和狀態(tài)欄一樣高的矩形
        View statusBarView = new View(activity);
        Log.i(TAG,"statusBarHeight:"+getStatusBarHeight());
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                getStatusBarHeight());
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(color);
        return statusBarView;
    }
    /**
     * 獲取statusBar高度
     */
    private int getStatusBarHeight(){
    int height = 0;
        int resourceId = getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = getApplicationContext().getResources().getDimensionPixelSize(resourceId);
        }
        return height;
    }

    /**
     * setFitsSystemWindows
     */
    private static void setRootView(Activity activity) {
        //獲取到activity_main.xml文件
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
        //如果不設置參數(shù),會使內(nèi)容顯示到狀態(tài)欄上
        rootView.setFitsSystemWindows(true);
    }
    /**
     * 創(chuàng)建barView
     */
    private void createBarView(int color) {
        //1、創(chuàng)建與statusBar相同高度的view
        View statusView = createStatusBarView(this, color);
        //2、添加statusView到布局中
        ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
        decorView.addView(statusView);
        //3、讓布局適應屏幕
        setRootView(this);
    }

直接調(diào)用createBarView方法即可實現(xiàn)效果


image.png

Android 5.0

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)     
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);           
window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));

由于Android 5.0新增API:setStatusBarColor,直接使用即可

Android 9.0

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)     
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);           
window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark))
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容