DecorView是Window的頂層view, 也就是說我們所有的控件都是包含在這個view中的. android7.0之前這個類是PhoneWindow的一個內部類, 7.0之后是一個獨立的類, 同時也增加了一些新的屬性和方法.
先看2張圖片:
我們想要實現第2張圖的效果, 應當在style中添加屬性 true 發現出來的效果是第一種, 上面竟然蒙了一層半透明view, 要想去除這層view也很簡單, 我們一般會在setContentView()之前添加一下代碼:
????????getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);?? //去除半透明狀態欄
????????getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);? //一般配合fitsSystemWindows()使用, 或者在根部局加上屬性android:fitsSystemWindows="true", 使根部局全屏顯示
????????getWindow().setStatusBarColor(Color.TRANSPARENT);
但是android7.0之后有時候我們通過上述方法還是不能去除蒙灰(原因尚不明確), 下面是7.0在DecorView中新添加的一部分源碼
DecorView(Context context, int featureId, PhoneWindow window, WindowManager.LayoutParams params) {
......
????????mForceWindowDrawsStatusBarBackground = ????????context.getResources().getBoolean(R.bool.config_forceWindowDrawsStatusBarBackground)
????????&& context.getApplicationInfo().targetSdkVersion >= N;
????????mSemiTransparentStatusBarColor = context.getResources().getColor(R.color.system_bar_background_semi_transparent, null);
......
}
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;
從源碼可以看到androidx.x之后會強制繪制statusbar的背景色, 而且在其他條件都滿足情況下還會加上半透明效果, 所以如果第一種方法去除不掉半透明的情況下可以通過反射拿到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) {}
????}
????????getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//7.0透明狀態欄
????//透明狀態欄
????if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//? ? ? ? ? ? getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);//完全隱藏狀態欄
????getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
????}
------>>在setContentView()之前通過反射修改mSemiTransparentStatusBarColor值