NotificationIconContainer.java
calculateIconTranslations(){
......
if (firstOverflowIndex != -1) { int numDots = 1; translationX = visualOverflowStart; for (int i = firstOverflowIndex; i < childCount; i++) { View view = getChildAt(i); IconState iconState = mIconStates.get(view); int dotWidth = mStaticDotRadius * 2 + mDotPadding; iconState.xTranslation = translationX; if (numDots <= 3) { if (numDots == 1 && iconState.iconAppearAmount < 0.8f) { iconState.visibleState = StatusBarIconView.STATE_ICON;//Icon显示为通知自己的Icon numDots--; } else { iconState.visibleState = StatusBarIconView.STATE_DOT;//Icon显示为一个点 } translationX += (numDots == 3 ? 3 * dotWidth : dotWidth) * iconState.iconAppearAmount; } else { iconState.visibleState = StatusBarIconView.STATE_HIDDEN; } numDots++; } }
}
控制Icon显示为点的控制是iconState.visibleState = StatusBarIconView.STATE_DOT;我们发现屏蔽该句代码,可以将显示为点的通知显示为图标,那我们看判断条件(numDots == 1 && iconState.iconAppearAmount < 0.8f)是如何控制的,但是我们发现该处并不能发现导致显示差异的根本原因,于是继续向上找判断,如果条件(firstOverflowIndex != -1)不成立,也不会执行iconState.visibleState = StatusBarIconView.STATE_DOT该段语句,不过我们要尝试屏蔽掉条件中的所有代码,看一下是否影响其他图标的显示,发现不影响,那么追看(firstOverflowIndex != -1)不成立的条件,在该方法中继续向上看,有赋值语句如下:
firstOverflowIndex = noOverflowAfter && !forceOverflow ? i - 1 : i;
继续向上看有
boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex && iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
发现forceOverflow和mSpeedBumpIndex有关,而StatusBar.java中 有方法updateSpeedBumpIndex方法,如下
private void updateSpeedBumpIndex() { int speedBumpIndex = 0; int currentIndex = 0; final int N = mStackScroller.getChildCount(); for (int i = 0; i < N; i++) { View view = mStackScroller.getChildAt(i); if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) { continue; } ExpandableNotificationRow row = (ExpandableNotificationRow) view; currentIndex++; if (!mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) { speedBumpIndex = currentIndex; } } boolean noAmbient = speedBumpIndex == N; mStackScroller.updateSpeedBumpIndex(speedBumpIndex, noAmbient); }
影响最终结果的是speedBumpIndex,看判断条件(!mNotificationData.isAmbient(row.getStatusBarNotification().getKey())),进入NotificationData的isAmbient方法,如下
public boolean isAmbient(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); return mTmpRanking.isAmbient(); } return false; }
再进入NotificationListenerService的isAmbient方法,如下
/** * Returns whether the notification is an ambient notification, that is * a notification that doesn't require the user's immediate attention. *返回通知是否为环境通知,即不需要用户立即关注的通知。 */ public boolean isAmbient() { return mIsAmbient; }
查看mIsAmbient的赋值位置,如下
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
也就是说通知的重要性小于IMPORTANCE_LOW的通知都是环境通知,会显示在通知栏的底部,上滑的过程中会显示为点,并且不会显示在状态栏中