Merge "Fix dot/icon overlap in notification shelf" into tm-qpr-dev
This commit is contained in:
@@ -423,6 +423,21 @@ public class NotificationIconContainer extends ViewGroup {
|
|||||||
+ getActualPaddingEnd();
|
+ getActualPaddingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean shouldForceOverflow(int i, int speedBumpIndex, float iconAppearAmount,
|
||||||
|
int maxVisibleIcons) {
|
||||||
|
return speedBumpIndex != -1 && i >= speedBumpIndex
|
||||||
|
&& iconAppearAmount > 0.0f || i >= maxVisibleIcons;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
|
||||||
|
float iconSize) {
|
||||||
|
// Layout end, as used here, does not include padding end.
|
||||||
|
final float overflowX = isLastChild ? layoutEnd : layoutEnd - iconSize;
|
||||||
|
return translationX >= overflowX;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the horizontal translations for each notification based on how much the icons
|
* Calculate the horizontal translations for each notification based on how much the icons
|
||||||
* are inserted into the notification container.
|
* are inserted into the notification container.
|
||||||
@@ -448,26 +463,26 @@ public class NotificationIconContainer extends ViewGroup {
|
|||||||
if (mFirstVisibleIconState == null) {
|
if (mFirstVisibleIconState == null) {
|
||||||
mFirstVisibleIconState = iconState;
|
mFirstVisibleIconState = iconState;
|
||||||
}
|
}
|
||||||
boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
|
|
||||||
&& iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
|
|
||||||
boolean isLastChild = i == childCount - 1;
|
|
||||||
float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
|
|
||||||
? ((StatusBarIconView) view).getIconScaleIncreased()
|
|
||||||
: 1f;
|
|
||||||
iconState.visibleState = iconState.hidden
|
iconState.visibleState = iconState.hidden
|
||||||
? StatusBarIconView.STATE_HIDDEN
|
? StatusBarIconView.STATE_HIDDEN
|
||||||
: StatusBarIconView.STATE_ICON;
|
: StatusBarIconView.STATE_ICON;
|
||||||
|
|
||||||
final float overflowDotX = layoutEnd - mIconSize;
|
final boolean forceOverflow = shouldForceOverflow(i, mSpeedBumpIndex,
|
||||||
boolean isOverflowing = translationX > overflowDotX;
|
iconState.iconAppearAmount, maxVisibleIcons);
|
||||||
|
final boolean isOverflowing = forceOverflow || isOverflowing(
|
||||||
|
/* isLastChild= */ i == childCount - 1, translationX, layoutEnd, mIconSize);
|
||||||
|
|
||||||
if (firstOverflowIndex == -1 && (forceOverflow || isOverflowing)) {
|
// First icon to overflow.
|
||||||
firstOverflowIndex = isLastChild && !forceOverflow ? i - 1 : i;
|
if (firstOverflowIndex == -1 && isOverflowing) {
|
||||||
|
firstOverflowIndex = i;
|
||||||
mVisualOverflowStart = layoutEnd - mIconSize;
|
mVisualOverflowStart = layoutEnd - mIconSize;
|
||||||
if (forceOverflow || mIsStaticLayout) {
|
if (forceOverflow || mIsStaticLayout) {
|
||||||
mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
|
mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
|
||||||
|
? ((StatusBarIconView) view).getIconScaleIncreased()
|
||||||
|
: 1f;
|
||||||
translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
|
translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
|
||||||
}
|
}
|
||||||
mNumDots = 0;
|
mNumDots = 0;
|
||||||
|
|||||||
@@ -153,6 +153,106 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
assertTrue(iconContainer.hasOverflow())
|
assertTrue(iconContainer.hasOverflow())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldForceOverflow_appearingAboveSpeedBump_true() {
|
||||||
|
val forceOverflow = iconContainer.shouldForceOverflow(
|
||||||
|
/* i= */ 1,
|
||||||
|
/* speedBumpIndex= */ 0,
|
||||||
|
/* iconAppearAmount= */ 1f,
|
||||||
|
/* maxVisibleIcons= */ 5
|
||||||
|
)
|
||||||
|
assertTrue(forceOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldForceOverflow_moreThanMaxVisible_true() {
|
||||||
|
val forceOverflow = iconContainer.shouldForceOverflow(
|
||||||
|
/* i= */ 10,
|
||||||
|
/* speedBumpIndex= */ 11,
|
||||||
|
/* iconAppearAmount= */ 0f,
|
||||||
|
/* maxVisibleIcons= */ 5
|
||||||
|
)
|
||||||
|
assertTrue(forceOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldForceOverflow_belowSpeedBumpAndLessThanMaxVisible_false() {
|
||||||
|
val forceOverflow = iconContainer.shouldForceOverflow(
|
||||||
|
/* i= */ 0,
|
||||||
|
/* speedBumpIndex= */ 11,
|
||||||
|
/* iconAppearAmount= */ 0f,
|
||||||
|
/* maxVisibleIcons= */ 5
|
||||||
|
)
|
||||||
|
assertFalse(forceOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_lastChildXLessThanLayoutEnd_false() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ true,
|
||||||
|
/* translationX= */ 0f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertFalse(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_lastChildXEqualToLayoutEnd_true() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ true,
|
||||||
|
/* translationX= */ 10f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertTrue(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ true,
|
||||||
|
/* translationX= */ 20f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertTrue(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_notLastChildXLessThanDotX_false() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ false,
|
||||||
|
/* translationX= */ 0f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertFalse(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_notLastChildXGreaterThanDotX_true() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ false,
|
||||||
|
/* translationX= */ 20f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertTrue(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_notLastChildXEqualToDotX_true() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ false,
|
||||||
|
/* translationX= */ 8f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertTrue(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
private fun mockStatusBarIcon() : StatusBarIconView {
|
private fun mockStatusBarIcon() : StatusBarIconView {
|
||||||
val iconView = mock(StatusBarIconView::class.java)
|
val iconView = mock(StatusBarIconView::class.java)
|
||||||
whenever(iconView.width).thenReturn(10)
|
whenever(iconView.width).thenReturn(10)
|
||||||
|
|||||||
Reference in New Issue
Block a user