1.相关类
- CollapsedStatusBarFragment.java
- StatusBar.java
2.原生隐藏控制逻辑
Android12 在锁屏界面开启时,状态栏显示电池电量,SIM状态和网络状态,隐藏掉了时间和通知等的显示(PanelView这些都会显示)
那么它是如何控制的呢?
在CollapsedStatusBarFragment.java中有一些flag可以控制,核心控制逻辑在adjustDisableFlags()方法中:
protected int adjustDisableFlags(int state) {
boolean headsUpVisible = mStatusBarComponent.headsUpShouldBeVisible();
if (headsUpVisible) {
state |= DISABLE_CLOCK;
}
//下面的三个Flag就可以控制相关ICON显示
if (!mKeyguardStateController.isLaunchTransitionFadingAway()
&& !mKeyguardStateController.isKeyguardFadingAway()
&& shouldHideNotificationIcons()
&& !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
&& headsUpVisible)) {
state |= DISABLE_NOTIFICATION_ICONS;
state |= DISABLE_SYSTEM_INFO;
state |= DISABLE_CLOCK;
}
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
if (mNetworkController.hasEmergencyCryptKeeperText()) {
state |= DISABLE_NOTIFICATION_ICONS;
}
if (!mNetworkController.isRadioOn()) {
state |= DISABLE_SYSTEM_INFO;
}
}
// The shelf will be hidden when dozing with a custom clock, we must show notification
// icons in this occasion.
if (mStatusBarStateController.isDozing()
&& mStatusBarComponent.getPanelController().hasCustomClock()) {
state |= DISABLE_CLOCK | DISABLE_SYSTEM_INFO;
}
if (mOngoingCallController.hasOngoingCall()) {
state &= ~DISABLE_ONGOING_CALL_CHIP;
} else {
state |= DISABLE_ONGOING_CALL_CHIP;
}
return state;
}
那么它是如何被调用的呢?
StatusBar在初始化的时候,会调用makeStatusBarView()方法,而CollapsedStatusBarFragment就是在此时控制显示的:
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
... ...
FragmentHostManager.get(mPhoneStatusBarWindow)
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
CollapsedStatusBarFragment statusBarFragment =
(CollapsedStatusBarFragment) fragment;
PhoneStatusBarView oldStatusBarView = mStatusBarView;
mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
mStatusBarView.setBar(this);
mStatusBarView.setPanel(mNotificationPanelViewController);
mStatusBarView.setScrimController(mScrimController);
mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners);
... ...
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container,
new CollapsedStatusBarFragment(
mOngoingCallController,
mAnimationScheduler,
mStatusBarLocationPublisher,
mNotificationIconAreaController,
mFeatureFlags,
mStatusBarIconController,
mKeyguardStateController,
mNetworkController,
mStatusBarStateController,
this,
mCommandQueue
),
CollapsedStatusBarFragment.TAG)
.commit();
}
而在显示过程中,会调用setPanelExpanded(boolean isExpanded)方法,该方法中updateHideIconsForBouncer(false );会通知CommandQueue控制Flag生效,调用到CollapsedStatusBarFragment的disable(…)方法,最后到核心逻辑adjustDisableFlags(…).
public void setPanelExpanded(boolean isExpanded) {
if (mPanelExpanded != isExpanded) {
mNotificationLogger.onPanelExpandedChanged(isExpanded);
}
mPanelExpanded = isExpanded;
updateHideIconsForBouncer(false );//控制隐藏
mNotificationShadeWindowController.setPanelExpanded(isExpanded);
mStatusBarStateController.setPanelExpanded(isExpanded);
if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
if (DEBUG) {
Log.v(TAG, "clearing notification effects from Height");
}
clearNotificationEffects();
}
if (!isExpanded) {
mRemoteInputManager.onPanelCollapsed();
}
}
private void updateHideIconsForBouncer(boolean animate) {
boolean hideBecauseApp = mTopHidesStatusBar && mIsOccluded
&& (mStatusBarWindowHidden || mBouncerShowing);
boolean hideBecauseKeyguard = !mPanelExpanded && !mIsOccluded && mBouncerShowing;
boolean shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard;
if (mHideIconsForBouncer != shouldHideIconsForBouncer) {
//注意这里将该值修改了,它会影响CollapsedStatusBarFragment:shouldHideNotificationIcons()
mHideIconsForBouncer = shouldHideIconsForBouncer;
if (!shouldHideIconsForBouncer && mBouncerWasShowingWhenHidden) {
// We're delaying the showing, since most of the time the fullscreen app will
// hide the icons again and we don't want them to fade in and out immediately again.
mWereIconsJustHidden = true;
mHandler.postDelayed(() -> {
mWereIconsJustHidden = false;
mCommandQueue.recomputeDisableFlags(mDisplayId, true);
}, 500);
} else {
mCommandQueue.recomputeDisableFlags(mDisplayId, animate);//重新计算Flag并生效
}
}
if (shouldHideIconsForBouncer) {
mBouncerWasShowingWhenHidden = mBouncerShowing;
}
}
上面注释里提到的注意,会改变mStatusBarComponent.hideStatusBarIconsForBouncer()的值,也就会影响是否disable掉三种ICON显示
private boolean shouldHideNotificationIcons() {
if (!mStatusBar.isClosed() && mStatusBarComponent.hideStatusBarIconsWhenExpanded()) {
return true;
}
if (mStatusBarComponent.hideStatusBarIconsForBouncer()) {
return true;
}
return false;
}
3.修改方法
上面的逻辑已经很清晰了,保证CollapsedStatusBarFragment.java不调用FLAG设置即可,具体如何还是看各位的需求。



