1. 程式人生 > >解決Android7.0下沉浸式狀態列變灰問題

解決Android7.0下沉浸式狀態列變灰問題

1.緒論

現在基本上所有的應用都會去實現沉浸式狀態列,這個是應用的標配,如果你開發的應用沒有,那這個吐槽點就多了,“這美工有審美觀麼”“程式猿這麼菜,沉浸式都不會?”….. 咳咳….. 開個玩笑啊,各有各的設計思想,不能怪程式猿。

2.問題

那麼說到沉浸式狀態列的問題是什麼呢?不知道大家有沒有遇到過,應用在android7.0系統以下的手機上執行,沉浸式狀態列是正常的,但是在7.0以上的手機上執行就感覺沒有沉浸式了,是分層的。無論怎麼修改狀態列背景色都沒用,看下圖:圖1是7.0以下執行效果,圖2是7.0以上執行效果。

Instagram Pic

Instagram Pic

看到上面兩幅圖,明顯感覺到7.0系統做了處理,在狀態列上蒙了一層灰色背景。

3.解決方法

首先,先普及下知識:
DecorView是整個Window介面的最頂層View,它只有一個子元素為LinearLayout。代表整個Window介面,包含通知欄,標題欄,內容顯示欄三塊區域。
DecorView這個大家應該很熟悉,通過getWindow().getDecorView()就可以得到此物件,在6.0以上,我們可以通過以下方式設定狀態列字型變黑:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

那麼可以猜想狀態列蒙灰肯定跟這個view有關。
接下來我們就去看DecorView的原始碼,對比Android6.0和7.0有什麼不同。你會發現Android7.0以下,DecorView是PhoneWindow的內部類,而在7.0以上,是一個單獨的類,並且有新的屬性和方法。新的屬性如:mSemiTransparentStatusBarColor,看字面意思應該就是我們要找的,我們對它進行跟蹤,與它相關的程式碼如下:

DecorView(Context context, int featureId, PhoneWindow window,WindowManager.LayoutParams params) {
        super(context);
......//省略無關程式碼 mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean( R.bool.config_forceWindowDrawsStatusBarBackground) && context.getApplicationInfo().targetSdkVersion >= N; //設定預設的值,灰色 mSemiTransparentStatusBarColor = context.getResources().getColor( R.color.system_bar_background_semi_transparent, null /* theme */); ......//省略無關程式碼 }
private int calculateStatusBarColor() {
    int flags = mWindow.getAttributes().flags;
    return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? mSemiTransparentStatusBarColor
                : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? mWindow.mStatusBarColor : Color.BLACK;
}

calculateStatusBarColor這個方法就是計算得到狀態列的顏色值,其中FLAG_TRANSLUCENT_STATUS是透明標識,如果flags與FLAG_TRANSLUCENT_STATUS相與不等於0的話就選擇預設灰色值mSemiTransparentStatusBarColor。
這個calculateStatusBarColor方法在updateColorViews方法中呼叫,而updateColorViews方法又在onWindowDragResizeStart、onWindowDragResizeEnd等方法呼叫(相關程式碼就不再帖了,請自行檢視原始碼),看到這裡就知道為啥怎麼修改狀態列顏色也沒用的原因了,這個背景色是動態算出來的。由此見得,只有將這個mSemiTransparentStatusBarColor變數值改為透明的就ok了。

那麼怎麼改呢?

解決思路:首先,我們通過getWindow().getDecorView()可以獲取到這個DecorView類的物件,然後通過反射修改這個物件的成員mSemiTransparentStatusBarColor變數值。程式碼如下:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    try {
        Class decorViewClazz = Class.forName("com.android.internal.policy.DecorView");
        Field field = decorViewClazz.getDeclaredField("mSemiTransparentStatusBarColor");
        field.setAccessible(true);  
        field.setInt(getWindow().getDecorView(), Color.TRANSPARENT);  //改為透明
    } catch (Exception e) {}
}

注意:這段程式碼需要在setContentView方法前呼叫。

核心程式碼都寫完了,趕緊試試吧!如果你覺得這篇文章對你有用,那麼贊一個或者留個言吧~

相關推薦

解決Android7.0沉浸狀態問題

1.緒論 現在基本上所有的應用都會去實現沉浸式狀態列,這個是應用的標配,如果你開發的應用沒有,那這個吐槽點就多了,“這美工有審美觀麼”“程式猿這麼菜,沉浸式都不會?”….. 咳咳….. 開個玩笑啊,各有各的設計思想,不能怪程式猿。 2.問題 那麼說到沉浸式

android全屏/沉浸狀態,各種鍵盤擋住輸入框解決辦法

*本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 在開發中,經常會遇到鍵盤擋住輸入框的情況,比如登入介面或註冊介面,彈出的軟鍵盤把登

(解決)android不同版本的【沉浸狀態】(4.4/5.0/5.1/6.0

介紹: 各個版本有略微的區別,下面我就根據自己的測試和除錯寫出對應的方法: 4.4以上(API>=19)的前提下,任選以下方法: 1.法1:只要呼叫一個方法,setContentView前: getWindow().addFlags(Win

Android 沉浸狀態完美解決方案

現在搜尋Android 沉浸式狀態列,真的是一堆一堆,寫的特別多,但是真正用的舒服的真沒有,在這裡自己整理一下開發記錄   注意,在使用這個步驟過程之前,請把之前設定的程式碼註釋一下 把佈局帶有android:fitsSystemWindows註釋掉 style檔案中凡是在style.xml

android系統版本6.0及以上設定沉浸狀態

系統版本6.0及以上設定沉浸式狀態列程式碼。   requestWindowFeature(Window.FEATURE_NO_TITLE); //系統版本6.0及以上設定沉浸式狀態列 if (RomUtil.hasM()) { int flag = getWindow().get

再回首沉浸狀態以及魅族手機等系統問題解決

        上次寫過一篇解決沉浸式狀態列問題的文章,不過當時僅僅是為了解決兩個問題,沒有過多理解過沉浸式,以至於每次發開需要沉浸式都需要網上搜索半天,然後拷貝程式碼過來,修改修改就得了,今天正好靜下心來好好思考了一下沉浸式。         頁面做成沉浸式的思路有兩個:

Android App 沉浸狀態解決方案

伴隨著 Android 5.0 釋出的 Material Design,讓 Android 應用告別了以前的工程師審美,迎來了全新的介面,靈動的互動,也讓越來越多的 App 開始遵從 material design 設計原則,不再是以前拿著iOS設計稿,做著Androi

沉浸狀態popWindow全屏顯示

沒有適配沉浸式狀態列 適配了沉浸式狀態列     PopWindow新增: setClippingEnabled(false);   Dial

Android 5.0以上Material Design 沉浸狀態

偶然在知乎上看到這個問題,Android 5.0 如何實現將佈局的內容延伸到狀態列,之前也見過多個應用的這個功能,但是知乎上的答案卻沒有一個真正實現此功能的一類是把標題欄設定App主題顏色,一類是提取App主題顏色然後設定成狀態列的顏色,這兩種方法都只是設定了狀態列的背景色,而沒有實現佈局延伸到狀態列這個

安卓沉浸狀態開發 輸入法彈出遮擋佈局問題解決

公司新版APP採用沉浸式狀態列開發,開發過程中遇到一些奇葩問題,其中一個問題就是輸入法彈出後,佈局沒有被頂上去,無法看到輸入內容 解決方案,在程式碼中,設定 getWindow().setSoftInputMode( WindowManager.LayoutPara

Android 沉浸狀態效果(狀態與內容完全融合、類似於iphone 7.0系統)

今天偶然間發現一種叫做沉浸式狀態列的、看了之後激動的非常、立馬開操! Activity的setContentView之前新增 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

Android5.0沉浸狀態,以及動態改變狀態顏色

設定狀態列完全不可見 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedIn

解決沉浸狀態底部導航與虛擬鍵衝突

if (Build.VERSION.SDK_INT >= 21) { View decorView = getWindow().getDecorView(); int option = View.SYSTE

沉浸狀態之Toolbar解決方案

1.style檔案中 去Title 狀態列透明 <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.N

【取什麼主題好呢】沉浸狀態----統一Title欄高度

新手上路 直接po程式碼(複製的時候記得加上setBar) 先是網上很好找到的“通過設定全屏,設定狀態列透明” /** * 通過設定全屏,設定狀態列透明 * @param activity */ public static void

vue專案 使用Hbuilder打包app 設定沉浸狀態

使用 Hbuilder新建好移動app專案後,mainfest.json這個檔案裡的 plus裡設定 statusbar ..... "plus": { "statusbar": { "immersed": true },

android 沉浸狀態(像ios那樣的狀態與應用統一顏色樣式)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

android4.4以上沉浸狀態和導航欄實現以及Bar的其他管理

自從android4.4開始,android手機狀態列再也不是一成黑的時代,之前叫做變色龍,miui6釋出會把他叫做沉浸式,之後大家就自然而然的接受了沉浸式這個名稱,其實實際應該叫做Translucent Bar,即為透明狀態列。   沉浸式實現原理其實是使整個activity佈局延伸到整個螢幕,然

移動端沉浸狀態H5 webAPP----(轉載學習)

2017年08月24日  ·  5.5k 次閱讀 H5+狀態列透明(沉浸式)/全屏/設定顏色 整理 移動端web H5+對web APP狀態列設定整理: 開發工具:HBuilder  直接新建移動APP專案 測試方法為HBuilder的i

Android中沉浸狀態,改變狀態顏色類似QQ樣式

1、使用該功能需要使用到第三方庫SystemBarTint 下載地址:https://github.com/jgilfelt/SystemBarTint 2、需要在AndroidMainfest檔案中Application設定樣式 android:the