100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android 7.0 SystemUI 状态/导航栏的隐藏与显示

Android 7.0 SystemUI 状态/导航栏的隐藏与显示

时间:2023-08-21 03:15:07

相关推荐

Android 7.0 SystemUI 状态/导航栏的隐藏与显示

平台

Android 7.1 + RK3288

概述

从Android 4.4开始支持沉浸式全屏体验,在沉浸式全屏模式下,状态栏、 虚拟按键动态隐藏,应用可以使用完整的屏幕空间,按照 Google 的说法,给用户一种 “身临其境” 的体验。

增加了 IMMERSIVE 和 IMMERSIVE_STICKY 标记,可以用这两个标记与 SYSTEM_UI_FLAG_HIDE_NAVIGATION 和 SYSTEM_UI_FLAG_FULLSCREEN 一起使用, 来实现沉 浸模式。

全屏的是通过隐藏状态栏和导航栏实现, 服务之间的交互如下:

关键函数

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

//顾名思义, 状态栏的控制器与导航栏的控制器, 设置显示/隐藏, 或临时显示都需要它private final StatusBarController mStatusBarController = new StatusBarController();private final BarController mNavigationBarController = new BarController("NavigationBar",View.NAVIGATION_BAR_TRANSIENT,View.NAVIGATION_BAR_UNHIDE,View.NAVIGATION_BAR_TRANSLUCENT,StatusBarManager.WINDOW_NAVIGATION_BAR,WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,View.NAVIGATION_BAR_TRANSPARENT);//WindowManagerService调用@Overridepublic int adjustSystemUiVisibilityLw(int visibility) {mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);// Reset any bits in mForceClearingStatusBarVisibility that// are now clear.mResettingSystemUiFlags &= visibility;// Clear any bits in the new visibility that are currently being// force cleared, before reporting it.return visibility & ~mResettingSystemUiFlags& ~mForceClearedSystemUiFlags;}//更新FLAG用, 比如, 会获取APP的指定FLAG, 再与前面的控制器交互并更新当前的系统FLAGprivate int updateSystemUiVisibilityLw() {// If there is no window focused, there will be nobody to handle the events// anyway, so just hang on in whatever state we're in until things settle down.WindowState winCandidate = mFocusedWindow != null ? mFocusedWindow: mTopFullscreenOpaqueWindowState;if (winCandidate == null) {return 0;}if (winCandidate.getAttrs().token == mImmersiveModeConfirmation.getWindowToken()) {// The immersive mode confirmation should never affect the system bar visibility,// otherwise it will unhide the navigation bar and hide itself.winCandidate = isStatusBarKeyguard() ? mStatusBar : mTopFullscreenOpaqueWindowState;if (winCandidate == null) {return 0;}}final WindowState win = winCandidate;if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) {// We are updating at a point where the keyguard has gotten// focus, but we were last in a state where the top window is// hiding it. This is probably because the keyguard as been// shown while the top window was displayed, so we want to ignore// it here because this is just a very transient change and it// will quickly lose focus once it correctly gets hidden.return 0;}int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)& ~mResettingSystemUiFlags& ~mForceClearedSystemUiFlags;if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) {tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);}final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */,mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds);mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds);final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);final int diff = visibility ^ mLastSystemUiFlags;final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags;final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu&& mFocusedApp == win.getAppToken()&& mLastNonDockedStackBounds.equals(mNonDockedStackBounds)&& mLastDockedStackBounds.equals(mDockedStackBounds)) {return 0;}mLastSystemUiFlags = visibility;mLastFullscreenStackSysUiFlags = fullscreenVisibility;mLastDockedStackSysUiFlags = dockedVisibility;mLastFocusNeedsMenu = needsMenu;mFocusedApp = win.getAppToken();final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds);final Rect dockedStackBounds = new Rect(mDockedStackBounds);mHandler.post(new Runnable() {@Overridepublic void run() {StatusBarManagerInternal statusbar = getStatusBarManagerInternal();if (statusbar != null) {//传递给SystemUIstatusbar.setSystemUiVisibility(visibility, fullscreenVisibility,dockedVisibility, 0xffffffff, fullscreenStackBounds,dockedStackBounds, win.toString());statusbar.topAppWindowChanged(needsMenu);}}});return diff;}private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {WindowState statusColorWin = isStatusBarKeyguard() && !mHideLockScreen? mStatusBar: opaqueOrDimming;if (statusColorWin != null) {if (statusColorWin == opaque) {// If the top fullscreen-or-dimming window is also the top fullscreen, respect// its light flag.vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)& View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;} else if (statusColorWin != null && statusColorWin.isDimming()) {// Otherwise if it's dimming, clear the light flag.vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;}}return vis;}private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);final boolean freeformStackVisible =mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID);final boolean resizing = mWindowManagerInternal.isDockedDividerResizing();// We need to force system bars when the docked stack is visible, when the freeform stack// is visible but also when we are resizing for the transitions when docked stack// visibility changes.mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing;final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;// apply translucent bar vis flagsWindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen? mStatusBar: mTopFullscreenOpaqueWindowState;vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);final int dockedVis = mStatusBarController.applyTranslucentFlagLw(mTopDockedOpaqueWindowState, 0, 0);final boolean fullscreenDrawsStatusBarBackground =(drawsSystemBarBackground(mTopFullscreenOpaqueWindowState)&& (vis & View.STATUS_BAR_TRANSLUCENT) == 0)|| forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState);final boolean dockedDrawsStatusBarBackground =(drawsSystemBarBackground(mTopDockedOpaqueWindowState)&& (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0)|| forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState);// prevent status bar interaction from clearing certain flagsint type = win.getAttrs().type;boolean statusBarHasFocus = type == TYPE_STATUS_BAR;if (statusBarHasFocus && !isStatusBarKeyguard()) {int flags = View.SYSTEM_UI_FLAG_FULLSCREEN| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_IMMERSIVE| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;if (mHideLockScreen) {flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT;}vis = (vis & ~flags) | (oldVis & flags);}if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {vis |= View.STATUS_BAR_TRANSPARENT;vis &= ~View.STATUS_BAR_TRANSLUCENT;} else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar)|| forceOpaqueStatusBar) {vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT);}vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing);// update status barboolean immersiveSticky =(vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;final boolean hideStatusBarWM =mTopFullscreenOpaqueWindowState != null&& (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null)& WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;final boolean hideStatusBarSysui =(vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;final boolean hideNavBarSysui =(vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;final boolean transientStatusBarAllowed = mStatusBar != null&& (statusBarHasFocus || (!mForceShowSystemBars&& (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky))));final boolean transientNavBarAllowed = mNavigationBar != null&& !mForceShowSystemBars && hideNavBarSysui && immersiveSticky;final long now = SystemClock.uptimeMillis();final boolean pendingPanic = mPendingPanicGestureUptime != 0&& now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) {// The user performed the panic gesture recently, we're about to hide the bars,// we're no longer on the Keyguard and the screen is ready. We can now request the bars.mPendingPanicGestureUptime = 0;mStatusBarController.showTransient();if (!isNavBarEmpty(vis)) {mNavigationBarController.showTransient();}}final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested()&& !transientStatusBarAllowed && hideStatusBarSysui;final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested()&& !transientNavBarAllowed;if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) {// clear the clearable flags insteadclearClearableFlagsLw();vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;}final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;final boolean navAllowedHidden = immersive || immersiveSticky;if (hideNavBarSysui && !navAllowedHidden && windowTypeToLayerLw(win.getBaseType())> windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) {// We can't hide the navbar from this window otherwise the input consumer would not get// the input events.vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);}vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis);// update navigation barboolean oldImmersiveMode = isImmersiveMode(oldVis);boolean newImmersiveMode = isImmersiveMode(vis);if (win != null && oldImmersiveMode != newImmersiveMode) {final String pkg = win.getOwningPackage();mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode,isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility()));}vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis);return vis;}

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

//SystemUI中处理由PWS传过来的FLAG.@Override // CommandQueuepublic void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {final int oldVal = mSystemUiVisibility;final int newVal = (oldVal&~mask) | (vis&mask);final int diff = newVal ^ oldVal;if (true) Log.d(TAG, String.format("setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",Integer.toHexString(vis), Integer.toHexString(mask),Integer.toHexString(oldVal), Integer.toHexString(newVal),Integer.toHexString(diff)));boolean sbModeChanged = false;if (diff != 0) {mSystemUiVisibility = newVal;// update low profileif ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {setAreThereNotifications();}// ready to unhideif ((vis & View.STATUS_BAR_UNHIDE) != 0) {mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;mNoAnimationOnNextBarModeChange = true;}// update status bar modefinal int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,View.STATUS_BAR_TRANSPARENT);// update navigation bar modefinal int nbMode = mNavigationBarView == null ? -1 : computeBarMode(oldVal, newVal, mNavigationBarView.getBarTransitions(),View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,View.NAVIGATION_BAR_TRANSPARENT);sbModeChanged = sbMode != -1;final boolean nbModeChanged = nbMode != -1;boolean checkBarModes = false;if (sbModeChanged && sbMode != mStatusBarMode) {mStatusBarMode = sbMode;checkBarModes = true;}if (nbModeChanged && nbMode != mNavigationBarMode) {mNavigationBarMode = nbMode;checkBarModes = true;}if (checkBarModes) {checkBarModes();}if (sbModeChanged || nbModeChanged) {// update transient bar autohideif (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {scheduleAutohide();} else {cancelAutohide();}}if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;}//变更新, 传递新的FLAG给WMS.// send updated sysui visibility to window managernotifyUiVisibilityChanged(mSystemUiVisibility);}mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);}

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

@Overridepublic void statusBarVisibilityChanged(int visibility) {Log.d(TAG, "statusBarVisibilityChanged 0x" + Integer.toHexString(visibility));if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Caller does not hold permission "+ android.Manifest.permission.STATUS_BAR);}synchronized (mWindowMap) {mLastStatusBarVisibility = visibility;//mPolicy == PhoneWindowManagervisibility = mPolicy.adjustSystemUiVisibilityLw(visibility);updateStatusBarVisibilityLocked(visibility);}}

一些常量

frameworks/base/core/java/android/view/View.java

public static final int STATUS_BAR_UNHIDE= 0x10000000;public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;public static final int STATUS_BAR_TRANSIENT= 0x04000000;public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY= 0x00001000;public static final int NAVIGATION_BAR_TRANSPARENT= 0x00008000;public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE= 0x00000100;public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN= 0x00000400;public static final int STATUS_BAR_TRANSPARENT = 0x0000008;

如前面在PhoneStatusBar中打印statusBarVisibilityChanged 0x的16进制字符串.

如:

隐藏->显示:

D/PhoneStatusBar: setSystemUiVisibility vis=3c009f0f mask=ffffffff oldVal=9f0f newVal=3c009f0f diff=3c000000

显示->隐藏:

D/PhoneStatusBar: setSystemUiVisibility vis=9f0f mask=ffffffff oldVal=c009f0f newVal=9f0f diff=c000000

一些干货

3秒的自动隐藏时间:

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

//3秒后自动隐藏private static final long AUTOHIDE_TIMEOUT_MS = 3000;private void scheduleAutohide() {cancelAutohide();mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);}

隐藏/显示动画

首先找出动画是SystemUI自己执行还是由WMS去执行, 答案是WMS, 看下打印出来的堆栈信息:

-09-08 18:44:51.850 467-1102/system_process W/System.err:at com.android.server.wm.WindowStateAnimator.setAnimation(WindowStateAnimator.java:275)-09-08 18:44:51.850 467-1102/system_process W/System.err:at com.android.server.wm.WindowStateAnimator.setAnimation(WindowStateAnimator.java:296)-09-08 18:44:51.852 467-1102/system_process W/System.err:at com.android.server.wm.WindowStateAnimator.applyAnimationLocked(WindowStateAnimator.java:1938)-09-08 18:44:51.852 467-1102/system_process W/System.err:at com.android.server.wm.WindowState.showLw(WindowState.java:1926)-09-08 18:44:51.852 467-1102/system_process W/System.err:at com.android.server.wm.WindowState.showLw(WindowState.java:1890)-09-08 18:44:51.852 467-1102/system_process W/System.err:at com.android.server.policy.BarController.setBarShowingLw(BarController.java:151)-09-08 18:44:51.853 467-1102/system_process W/System.err:at com.android.server.policy.BarController.adjustSystemUiVisibilityLw(BarController.java:116)-09-08 18:44:51.853 467-1102/system_process W/System.err:at com.android.server.policy.PhoneWindowManager.adjustSystemUiVisibilityLw(PhoneWindowManager.java:4124)-09-08 18:44:51.853 467-1102/system_process W/System.err:at com.android.server.wm.WindowManagerService.statusBarVisibilityChanged(WindowManagerService.java:10951)

动画资源

函数有对状态栏和导航栏对应进出资源的判断.

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

/** {@inheritDoc} */@Overridepublic int selectAnimationLw(WindowState win, int transit) {if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win+ ": transit=" + transit);if (win == mStatusBar) {boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;if (transit == TRANSIT_EXIT|| transit == TRANSIT_HIDE) {return isKeyguard ? -1 : R.anim.dock_top_exit;} else if (transit == TRANSIT_ENTER|| transit == TRANSIT_SHOW) {return isKeyguard ? -1 : R.anim.dock_top_enter;}} else if (win == mNavigationBar) {if (win.getAttrs().windowAnimations != 0) {return 0;}// This can be on either the bottom or the right or the left.if (mNavigationBarPosition == NAV_BAR_BOTTOM) {if (transit == TRANSIT_EXIT|| transit == TRANSIT_HIDE) {if (isKeyguardShowingAndNotOccluded()) {return R.anim.dock_bottom_exit_keyguard;} else {return R.anim.dock_bottom_exit;}} else if (transit == TRANSIT_ENTER|| transit == TRANSIT_SHOW) {return R.anim.dock_bottom_enter;}} else if (mNavigationBarPosition == NAV_BAR_RIGHT) {if (transit == TRANSIT_EXIT|| transit == TRANSIT_HIDE) {return R.anim.dock_right_exit;} else if (transit == TRANSIT_ENTER|| transit == TRANSIT_SHOW) {return R.anim.dock_right_enter;}} else if (mNavigationBarPosition == NAV_BAR_LEFT) {if (transit == TRANSIT_EXIT|| transit == TRANSIT_HIDE) {return R.anim.dock_left_exit;} else if (transit == TRANSIT_ENTER|| transit == TRANSIT_SHOW) {return R.anim.dock_left_enter;}}} else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) {return selectDockedDividerAnimationLw(win, transit);}if (transit == TRANSIT_PREVIEW_DONE) {if (win.hasAppShownWindows()) {if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");return com.android.internal.R.anim.app_starting_exit;}} else if (win.getAttrs().type == TYPE_DREAM && mDreamingLockscreen&& transit == TRANSIT_ENTER) {// Special case: we are animating in a dream, while the keyguard// is shown. We don't want an animation on the dream, because// we need it shown immediately with the keyguard animating away// to reveal it.return -1;}return 0;}

在后续一些定制修改中, 强制修改了FLAG让状态栏一直显示.

在全屏应用下, 系统会再次使StatusBar隐藏, 原因在于layout完成后,会再确认顶层应用窗口是否全屏, 并对应设置Window是否显示, 此过程无动画

-09-09 18:05:05.679 449-562/system_process W/System.err:at com.android.server.policy.BarController.updateStateLw(BarController.java:194)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.policy.BarController.setBarShowingLw(BarController.java:166)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.policy.PhoneWindowManager.finishPostLayoutPolicyLw(PhoneWindowManager.java:5511)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.wm.WindowSurfacePlacer.applySurfaceChangesTransaction(WindowSurfacePlacer.java:674)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementInner(WindowSurfacePlacer.java:320)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:235)-09-09 18:05:05.680 449-562/system_process W/System.err:at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:184)

finishPostLayoutPolicyLw中调用setBarShowingLw, 把状态栏隐藏了, 若需保持状态栏一直显示, 需处理这部分代码

mStatusBarController.setBarShowingLw(false);

多使用dumpsys

dumpsys window

//实时查看服务的变量状态mOrientationSensorEnabled=truemOverscanScreen=(0,0) 1920x1080mRestrictedOverscanScreen=(0,0) 1920x1080mUnrestrictedScreen=(0,0) 1920x1080mRestrictedScreen=(0,0) 1920x1080mStableFullscreen=(0,0)-(1920,1024)mStable=(0,24)-(1920,1024)mSystem=(0,0)-(1920,1080)mCur=(0,24)-(1920,1080)mContent=(0,24)-(1920,1080)mVoiceContent=(0,24)-(1920,1080)mDock=(0,24)-(1920,1080)//状态栏被mStatusBarController.setBarShowingLw(false);隐藏时:Window #7 Window{1633372 u0 StatusBar}:mDisplayId=0 stackId=0 mSession=Session{f3c2053 644:u0a10018} mClient=android.os.BinderProxy@236987dmOwnerUid=10018 mShowToOwnerOnly=false package=com.android.systemui appop=NONEmAttrs=WM.LayoutParams{(0,0)(fillx24) taskId=-1 gr=#30 sim=#10 ty=2000 fl=#81840048 fmt=-3 vsysui=0x600}Requested w=1920 h=24 mLayoutSeq=85mPolicyVisibility=false mPolicyVisibilityAfterAnim=false mAppOpVisibility=true mAttachedHidden=falsemPermanentlyHidden=falsemHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=false hasSavedSurface()=false mWindowRemovalAllowed=falseWindowStateAnimator{7a4071f StatusBar}:Surface: shown=false layer=161000 alpha=1.0 rect=(0.0,0.0) 1920.0 x 24.0----------------------------------//状态栏显示时Window #5 Window{1633372 u0 StatusBar}:mDisplayId=0 stackId=0 mSession=Session{f3c2053 644:u0a10018} mClient=android.os.BinderProxy@236987dmOwnerUid=10018 mShowToOwnerOnly=false package=com.android.systemui appop=NONEmAttrs=WM.LayoutParams{(0,0)(fillx24) taskId=-1 gr=#30 sim=#10 ty=2000 fl=#81840048 fmt=-3 vsysui=0x600}Requested w=1920 h=24 mLayoutSeq=163mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=falseWindowStateAnimator{7a4071f StatusBar}:mAnimating=false mLocalAnimating=false mAnimationIsEntrance=true mAnimation=null mStackClip=1Surface: shown=true layer=161000 alpha=1.0 rect=(0.0,0.0) 1920.0 x 24.0------------------------------------------------------//状态栏隐藏动画过程Window #5 Window{16f510e u0 StatusBar}:mDisplayId=0 stackId=0 mSession=Session{5e171f4 632:u0a10018} mClient=android.os.BinderProxy@3e87b09mOwnerUid=10018 mShowToOwnerOnly=false package=com.android.systemui appop=NONEmAttrs=WM.LayoutParams{(0,0)(fillx24) taskId=-1 gr=#30 sim=#10 ty=2000 fl=#81840048 fmt=-3 vsysui=0x600}Requested w=1920 h=24 mLayoutSeq=69mPolicyVisibility=true mPolicyVisibilityAfterAnim=false mAppOpVisibility=true mAttachedHidden=falsemPermanentlyHidden=falsemHasSurface=true mShownPosition=[0,-4] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=falseWindowStateAnimator{2214d2c StatusBar}:mAnimating=true mLocalAnimating=true mAnimationIsEntrance=false mAnimation=android.view.animation.AnimationSet@5de858d mStackClip=0XForm: has=true hasLocal=true {alpha=1.0 matrix=[1.0, 0.0, 0.0][0.0, 1.0, -3.5060544][0.0, 0.0, 1.0]}Surface: shown=true layer=161000 alpha=1.0 rect=(0.0,-4.0) 1920.0 x 24.0mGlobalScale=1.0 mDsDx=1.0 mDtDx=0.0 mDsDy=0.0 mDtDy=1.0

修改了状态栏FLAG后, 窗口布局(大小/位置)不正确可以看看这个函数, 多打打df, vf, cf …的值

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

public void layoutWindowLw(WindowState win, WindowState attached, int width, int height) {// We've already done the navigation bar and status bar. If the status bar can receive// input, we need to layout it again to accomodate for the IME window.if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) {return;}final WindowManager.LayoutParams attrs = win.getAttrs();final boolean isDefaultDisplay = win.isDefaultDisplay();final boolean needsToOffsetInputMethodTarget = isDefaultDisplay &&(win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null);if (needsToOffsetInputMethodTarget) {if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state");offsetInputMethodWindowLw(mLastInputMethodWindow);}final int fl = PolicyControl.getWindowFlags(win, attrs);final int pfl = attrs.privateFlags;final int sim = attrs.softInputMode;final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null);final Rect pf = mTmpParentFrame;final Rect df = mTmpDisplayFrame;final Rect of = mTmpOverscanFrame;final Rect cf = mTmpContentFrame;final Rect vf = mTmpVisibleFrame;final Rect dcf = mTmpDecorFrame;final Rect sf = mTmpStableFrame;//省略N行代码.....if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()+ ": sim=#" + Integer.toHexString(sim)+ " attach=" + attached + " type=" + attrs.type+ String.format(" flags=0x%08x", fl)+ " pf=" + pf.toShortString() + " df=" + df.toShortString()+ " of=" + of.toShortString()+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString()+ " dcf=" + dcf.toShortString()+ " sf=" + sf.toShortString()+ " osf=" + (osf == null ? "null" : osf.toShortString()));puteFrameLw(pf, df, of, cf, vf, dcf, sf, osf);}

扩展

Android 沉浸式状态栏

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。