概述
自 Android 5.0 版本,Android 带来了沉浸式系统 bar(状态栏和导航栏),Android 的视觉效果进一步提高,各大 app 厂商也在大多数场景上使用沉浸式效果。6.0开始提供了View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR标志位,将状态栏设置为浅色模式, 清除掉这个标志, 可以恢复为深色模式.
引自:Android M如何设置状态栏图标黑白色
App调用方法
主题设置加入, 暗灰图标
<item name="android:windowLightStatusBar">true</item>
代码中实现切换
public static void changeStatusBarContrastStyle(Window window, Boolean lightIcons) { View decorView = window.getDecorView(); if (lightIcons) { // Draw light icons on a dark background color decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else { // Draw dark icons on a light background color decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } }
需要更高SDK支持:
//icon color -> black activity.getWindow().getDecorView().getWindowInsetsController().setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS); //icon color -> white activity.getWindow().getDecorView().getWindowInsetsController().setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS);
色调变化流程
frameworks/base/core/java/android/view/View.java
@Deprecated public void setSystemUiVisibility(int visibility) { if (visibility != mSystemUiVisibility) { mSystemUiVisibility = visibility; if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) { mParent.recomputeViewAttributes(this); } } }
frameworks/base/core/java/android/view/ViewRootImpl.java
@Override public void recomputeViewAttributes(View child) { checkThread(); if (mView == child) { mAttachInfo.mRecomputeGlobalAttributes = true; if (!mWillDrawSoon) { scheduleTraversals(); } } }
frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java
int updateSystemUiVisibilityLw() { //...Ignore.... mHandler.post(() -> { StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); if (statusBar != null) { final int displayId = getDisplayId(); statusBar.setDisableFlags(displayId, visibility & StatusBarManager.DISABLE_MASK, cause); if (transientState.first.length > 0) { statusBar.showTransient(displayId, transientState.first); } if (transientState.second.length > 0) { statusBar.abortTransient(displayId, transientState.second); } statusBar.onSystemBarAppearanceChanged(displayId, appearance, appearanceRegions, isNavbarColorManagedByIme); statusBar.topAppWindowChanged(displayId, isFullscreen, isImmersive); // TODO(b/118118435): Remove this after removing system UI visibilities. synchronized (mLock) { mDisplayContent.statusBarVisibilityChanged( visibility & ~(View.STATUS_BAR_UNHIDE | View.NAVIGATION_BAR_UNHIDE)); } } }); return diff; }
SystemUI中的流程简单梳理下:
参考
Android statusbar icons color
[ANDROID] 狀態欄(STATUS BAR)文字與圖示轉換成灰色
Android 系统 Bar 沉浸式完美兼容方案
全屏、沉浸式、fitSystemWindow使用及原理分析:全方位控制“沉浸式”的实现