1. 程式人生 > >android介面UI美化:沉浸模式、全透明或半透明狀態列及導航欄的實現

android介面UI美化:沉浸模式、全透明或半透明狀態列及導航欄的實現

android api19開始我們就能對頂部狀態列和底部導航欄進行半透明處理了,而api21開始則可以實現全透明狀態列與導航欄以及開啟沉浸模式,至於什麼是沉浸模式,大家百度一下應該就都知道了,有一點需要強調的是全透明不是沉浸模式,前者只是將狀態列、導航欄的背景設定為完全透明,而後者則是完全將狀態列與導航欄隱藏並且只要在螢幕頂部下滑或在底部上滑就能短暫撥出狀態列與導航欄當然幾秒鐘之後還是會隱藏的;

下面三張圖的效果分別是:普通狀態列,半透明狀態列,全透明狀態列




下面看方法:

/**
 * 設定透明狀態列與導航欄
 * @param navi true不設定導航欄|false設定導航欄
 */
public void setStatusBar(boolean navi) {
    //api>21,全透明狀態列和導航欄;api>19,半透明狀態列和導航欄
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
        if (navi) {
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN//狀態列不會被隱藏但activity佈局會擴充套件到狀態列所在位置
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION//導航欄不會被隱藏但activity佈局會擴充套件到導航欄所在位置
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.setNavigationBarColor(Color.TRANSPARENT);
        } else {
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        }
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        if (navi) {
            //半透明導航欄
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
        //半透明狀態列
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }
}
/**
 * 進入沉浸模式
 * @param view view
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void hideSystemUI(View view) {
    view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY//會自動隱藏
    );
}

/**
 * 退出沉浸模式
 * @param view view
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void showSystemUI(View view) {
    view.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
注意:狀態列或導航欄進行透明處理之後,咱們的佈局內容是會擴充套件到原來狀態列與導航欄的位置,但是這樣就會造成狀態列顯示的內容與我們的佈局內容重疊,所以接下來
還需要進行一步處理,本人偷懶所以只是在程式碼中獲取頁面最上面的控制元件進行paddingTop出狀態列的高度(國內大多數品牌的手機都是沒有底部導航欄的,所以不做處理)
獲取狀態列高度的程式碼:

 
/**
 * 獲取狀態列高度
 *
 * @param context 上下文
 * @return 狀態列高度
 */
public int getStatusBarHeight(Context context) {
    int statusBarHeight = 0;
    try {
        Class<?> clazz = Class.forName("com.android.internal.R$dimen");
        Object obj = clazz.newInstance();
        Field field = clazz.getField("status_bar_height");
        int temp = Integer.parseInt(field.get(obj).toString());
        statusBarHeight = context.getResources().getDimensionPixelSize(temp);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return statusBarHeight;
}

 

 
主要的幾個flag:
public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;  隱藏導航欄

 

 
public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;  字面意思是全屏顯示,實際是狀態列會被隱藏而導航欄未作處理

 

 
public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;  導航欄不會被隱藏但佈局會擴充套件到導航欄所在位置

 

 
public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;  狀態列不會被隱藏但佈局會擴充套件到狀態列所在位置

 

 
public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;  配合SYSTEM_UI_FLAG_HIDE_NAVIGATION使用,如果只有SYSTEM_UI_FLAG_HIDE_NAVIGATION而不設定SYSTEM_UI_FLAG_IMMERSIVE,那麼使用者互動後會自動清除SYSTEM_UI_FLAG_HIDE_NAVIGATION這個flag;

 

 
public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;  配合SYSTEM_UI_FLAG_HIDE_NAVIGATION和(或)SYSTEM_UI_FLAG_FULLSCREEN使用,設定這個flag之後,使用者在螢幕頂部下滑或者在底部上滑調出狀態列、導航欄之後它們仍會自動隱藏;

add on 2017.09.19:


 

Android 4.4 以下進入全屏

直接給Window新增全屏標記位

activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);


 
  • 1
  • 2

同時,為了不讓佈局因SystemUI的可見或隱藏而重新layout,可以給Window新增FLAG_LAYOUT_IN_SCREEN和FLAG_LAYOUT_NO_LIMITS,這樣SystemUI出現時候是overlay在佈局內容的上面。

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);    
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);