Android實現沉浸式狀態欄的那些坑

最近項目需要實現沉浸式的狀態欄,其實我在之前就瞭解過Android的沉浸式,發現有些棘手就放棄了,但是此次是公司的項目需要的,就花了幾天把這個問題搞定了,在此記錄一下,並mark幾個坑。
首先,沉浸式是Android 4.4及以上纔有的,在後續的5.0及6.0上面都增加了一些相關支持,於是問題就不太好辦了。先看我實現的效果:
這裏寫圖片描述
首先,在4.4版本添加了WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS 和 WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,即透明的狀態欄和導航欄,這裏一般會配合

android:fitsSystemWindows="true"  
android:clipToPadding="true"  

一起使用,這裏只給個鏈接:http://blog.csdn.net/jdsjlzx/article/details/46778631
於是,下面就說說遇到的問題:

第一坑:狀態欄背景色

上面的FLAG_TRANSLUCENT_STATUS 只是把狀態欄設置爲透明的,但是!但是,狀態欄是有背景色的,一些手機的狀態欄背景色爲透明,而一些手機的狀態欄背景色爲半透明的黑色,實現的效果如下:
這裏寫圖片描述
於是在5.0上增加了WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 和 getWindow().setStatusBarColor(int color),一般使用如下:

// 部分機型的statusbar會有半透明的黑色背景
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21

於是,在5.0才能看到清爽的全透狀態欄。

第二坑:狀態欄字體顏色

狀態欄的字體顏色默認爲白色的,但是我們應用的主題色爲黃色,白色字體在黃色背景上是不易分辨的,所以這裏得把狀態欄的字體改爲深色,想想這個也是不太好做(其實這個在IOS上面自帶的效果),但是在6.0增加了View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,這個字段就是把狀態欄標記爲淺色,然後狀態欄的字體顏色自動轉換爲深色。
所以,如果需要淺色的狀態欄,只能在Android6.0及以後的版本中實現。
這裏暗藏一個坑:MIUI6+自己實現了淺色狀態欄,但是6.0的這個設置在小米手機上無效,真是 * * *!給個MIUI6沉浸式開發文檔:http://dev.xiaomi.com/doc/p=4769/

第三坑:輸入框頂不起來

原以爲效果實現了就萬事大吉,結果後面發現加入沉浸式之後,聊天頁面底部的輸入框不能被輸入法頂起來
這裏寫圖片描述
紅色框那裏本應該是輸入框的。
網上找了好多資料,都說需要加入android:fitsSystemWindows=”true”,但是在activity的根佈局加入該屬性後,titlebar也會跟着鍵盤頂上去,這顯然不是我們想要的結果。後面看到有人說,只需要把該屬性添加到輸入框所在的根佈局,按這個方法果然解決問題了:
這裏寫圖片描述
好了,遇到的幾個坑都解決了,後面發現新坑再補充!

另一個沉浸式實現方案:Android沉浸式通知欄開源庫SystemBarTint源碼解析


在BaseActivity添加如下方法:

    /**
     * 初始化狀態欄相關,
     * PS: 設置全屏需要在調用super.onCreate(arg0);之前設置setIsFullScreen(true);否則在Android 6.0下非全屏的activity會出錯;
     * SDK19:可以設置狀態欄透明,但是半透明的SYSTEM_BAR_BACKGROUNDS會不好看;
     * SDK21:可以設置狀態欄顏色,並且可以清除SYSTEM_BAR_BACKGROUNDS,但是不能設置狀態欄字體顏色(默認的白色字體在淺色背景下看不清楚);
     * SDK23:可以設置狀態欄爲淺色(SYSTEM_UI_FLAG_LIGHT_STATUS_BAR),字體就回反轉爲黑色。
     * 爲兼容目前效果,僅在SDK23才顯示沉浸式。
     */
    private void initStatusBar() {
        Window win = getWindow();
        if (mIsFullScreen) {
            win.requestFeature(Window.FEATURE_NO_TITLE);
            win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息欄
            win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 保持屏幕高亮
        } else {
            //KITKAT也能滿足,只是SYSTEM_UI_FLAG_LIGHT_STATUS_BAR(狀態欄字體顏色反轉)只有在6.0纔有效
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                win.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明狀態欄
                // 狀態欄字體設置爲深色,SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 爲SDK23增加
                win.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

                // 部分機型的statusbar會有半透明的黑色背景
                win.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                win.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                win.setStatusBarColor(Color.TRANSPARENT);// SDK21

                isStatusBarTranslate = true;
            }
        }
    }
發佈了124 篇原創文章 · 獲贊 114 · 訪問量 226萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章