Android 狀態欄全透明策略

#Android 狀態欄全透明策略android

@(Android)git

展現效果:

Android4.4如下: 狀態欄黑乎乎一片 
這裏寫圖片描述github

Android4.4之後, 能夠將狀態欄設置爲透明, 或者任意顏色 
1. 全屏模式 
這裏寫圖片描述 
2. 着色模式 
這裏寫圖片描述ide

Demo

Github Demo 連接: StatusBarCompat函數

參考文章

Android開發:Translucent System Bar 的最佳實踐 
Android狀態欄一體化ui

內容介紹

這篇文章主要是對實現狀態欄一體化的一些總結, 參考上面兩篇文章, 寫得很棒, 推薦你們都看一看! 
實現狀態欄一體化, 主要分爲兩種方式. 一種是經過xml配置文件設置, 一種是經過在activity中設置屬性. 下面將介紹兩種實現方法:this

1. 經過配置文件實現

在Android4.4以後提供了能夠修改狀態欄的屬性接口後,咱們能夠直接經過style文件來配置狀態欄, 可是須要注意的是, 爲了兼容4.4如下的版本, 因此必須在配置多個API級別的values文件. 這裏直接借參考文章中的圖: 
這裏寫圖片描述 
最基本的在4.4版本之下會加載默認的values/styles.xml, 若是在4.4版本會加載 values-v19/styles.xml, 5.0以上加載 values-v21/styles.xml文件. 具體配置以下:spa

values/styles.xml.net

<style name="ImageTranslucentTheme" parent="AppTheme">
    <!--在Android 4.4以前的版本上運行,直接跟隨系統主題-->
</style>
  • 1
  • 2
  • 3

values-v19/styles.xmlcode

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>
  • 1
  • 2
  • 3
  • 4

values-v21/styles.xml

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <!--Android 5.x開始須要把顏色設置透明,不然導航欄會呈現系統默認的淺灰色-->
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. 經過代碼中設置

經過代碼控制, 須要根據不一樣的版本sdk作不一樣的設置. 下面的代碼將詳細說明:

2. 1全屏模式

全屏模式的意思就是: 狀態欄顯示, 狀態欄背景透明, 因此會呈現根Layout的背景.以下圖: 
這裏寫圖片描述

Android5.0版本以上

// 5.0版本以上
    private void setStatusBarUpperAPI21() {
        Window window = getWindow();
        //設置透明狀態欄,這樣才能讓 ContentView 向上
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        //須要設置這個 flag 才能調用 setStatusBarColor 來設置狀態欄顏色
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

        ViewGroup mContentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
        View mChildView = mContentView.getChildAt(0);
        if (mChildView != null) {
            //注意不是設置 ContentView 的 FitsSystemWindows, 而是設置 ContentView 的第一個子 View . 使其不爲系統 View 預留空間.
            ViewCompat.setFitsSystemWindows(mChildView, false);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Android4.4版本-Adnroid5.0版本

// 4.4 - 5.0版本
    private void setStatusBarUpperAPI19() {
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        ViewGroup mContentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
        View statusBarView = mContentView.getChildAt(0);
        //移除假的 View
        if (statusBarView != null && statusBarView.getLayoutParams() != null &&
                statusBarView.getLayoutParams().height == getStatusBarHeight()) {
            mContentView.removeView(statusBarView);
        }
        //不預留空間
        if (mContentView.getChildAt(0) != null) {
            ViewCompat.setFitsSystemWindows(mContentView.getChildAt(0), false);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2. 2着色模式

着色模式的意思是:狀態欄顯示,狀態欄的背景顏色須要設置.以下圖: 
這裏寫圖片描述

Android5.0版本以上

private void setStatusBarUpperAPI21(){
        Window window = getWindow();
        //取消設置透明狀態欄,使 ContentView 內容再也不覆蓋狀態欄
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        //須要設置這個 flag 才能調用 setStatusBarColor 來設置狀態欄顏色
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        //設置狀態欄顏色
        //因爲setStatusBarColor()這個API最低版本支持21, 本人的是15,因此若是要設置顏色,自行到style中經過配置文件設置
//        window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
        ViewGroup mContentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
        View mChildView = mContentView.getChildAt(0);
        if (mChildView != null) {
            //注意不是設置 ContentView 的 FitsSystemWindows, 而是設置 ContentView 的第一個子 View . 預留出系統 View 的空間.
            ViewCompat.setFitsSystemWindows(mChildView, true);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Android4.4版本-Adnroid5.0版本

private void setStatusBarUpperAPI19() {
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        ViewGroup mContentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
        int statusBarHeight = getStatusBarHeight();
        int statusColor = getResources().getColor(R.color.colorPrimary);

        View mTopView = mContentView.getChildAt(0);
        if (mTopView != null && mTopView.getLayoutParams() != null &&
                mTopView.getLayoutParams().height == statusBarHeight) {
            //避免重複添加 View
            mTopView.setBackgroundColor(statusColor);
            return;
        }
        //使 ChildView 預留空間
        if (mTopView != null) {
            ViewCompat.setFitsSystemWindows(mTopView, true);
        }

        //添加假 View
        mTopView = new View(this);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);
        mTopView.setBackgroundColor(statusColor);
        mContentView.addView(mTopView, 0, lp);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2.3 公共函數

在onCreate()中初始化StatusBar

@Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_drawcolor_mode);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                setStatusBarUpperAPI21();
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                setStatusBarUpperAPI19();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

獲取狀態欄高度函數

private int getStatusBarHeight(){
        int result = 0;
        int resId = getResources().getIdentifier("status_bar_height","dimen","android");
        if(resId>0){
            result = getResources().getDimensionPixelSize(resId);
        }
        return result;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

關於NavigationBar的隱藏

若是你用的是Neux手機, 就會發現手機下面還有NavigationBar, 就是退出,Home,程序 3個按鍵的軟鍵盤. 在全屏模式中, 是沒法隱藏掉NavigationBar的. 下面的代碼提供隱藏的方法, 可講代碼加入到全屏模式的Activity中:

/**
     * 用於控制NavigationBar的隱藏和顯示
     */
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        }
    }

    private void showSystemUI() {
        mDecorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

    private void hideSystemUI() {
        mDecorView.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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Demo地址

 

21以後 起做用設置。

//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//            getWindow().setStatusBarColor(Color.TRANSPARENT);
相關文章
相關標籤/搜索