概述
自 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 colordecorView.setSystemUiVisibility(decorView.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);} else {// Draw dark icons on a light background colordecorView.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
@Deprecatedpublic 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
@Overridepublic 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使用及原理分析:全方位控制“沉浸式”的实现