diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index c255eb54a7..8026d4acfb 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -191,7 +191,6 @@ public class ActivityAllAppsContainerView private float mBottomSheetAlpha = 1f; private boolean mForceBottomSheetVisible; private int mTabsProtectionAlpha; - private float mTotalHeaderProtectionHeight; @Nullable private AllAppsTransitionController mAllAppsTransitionController; public ActivityAllAppsContainerView(Context context) { @@ -778,7 +777,7 @@ public class ActivityAllAppsContainerView protected void updateHeaderScroll(int scrolledOffset) { float prog1 = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f); int headerColor = getHeaderColor(prog1); - int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0 + int tabsAlpha = mHeader.getPeripheralProtectionHeight(/* expectedHeight */ false) == 0 ? 0 : (int) (Utilities.boundToRange( (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f) * 255); @@ -1448,15 +1447,13 @@ public class ActivityAllAppsContainerView mTmpPath.reset(); mTmpPath.addRoundRect(mTmpRectF, mBottomSheetCornerRadii, Direction.CW); canvas.drawPath(mTmpPath, mHeaderPaint); - mTotalHeaderProtectionHeight = headerBottomWithScaleOnTablet; } } else { canvas.drawRect(0, 0, canvas.getWidth(), headerBottomWithScaleOnPhone, mHeaderPaint); - mTotalHeaderProtectionHeight = headerBottomWithScaleOnPhone; } // If tab exist (such as work profile), extend header with tab height - final int tabsHeight = headerView.getPeripheralProtectionHeight(); + final int tabsHeight = headerView.getPeripheralProtectionHeight(/* expectedHeight */ false); if (mTabsProtectionAlpha > 0 && tabsHeight != 0) { if (DEBUG_HEADER_PROTECTION) { mHeaderPaint.setColor(Color.BLUE); @@ -1482,16 +1479,19 @@ public class ActivityAllAppsContainerView right, tabBottomWithScale, mHeaderPaint); - mTotalHeaderProtectionHeight = tabBottomWithScale; } } /** - * The height of the header protection is dynamically calculated during the time of drawing the - * header. + * The height of the header protection as if the user scrolled down the app list. */ float getHeaderProtectionHeight() { - return mTotalHeaderProtectionHeight; + float headerBottom = getHeaderBottom() - getTranslationY(); + if (mUsingTabs) { + return headerBottom + mHeader.getPeripheralProtectionHeight(/* expectedHeight */ true); + } else { + return headerBottom; + } } /** @@ -1515,6 +1515,10 @@ public class ActivityAllAppsContainerView return bottom + mHeader.getTop(); } + boolean isUsingTabs() { + return mUsingTabs; + } + /** * Returns a view that denotes the visible part of all apps container view. */ diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java index a1f6ebe557..ecba23f2cc 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderView.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -466,9 +466,14 @@ public class FloatingHeaderView extends LinearLayout implements } /** - * Returns visible height of FloatingHeaderView contents requiring header protection + * Returns visible height of FloatingHeaderView contents requiring header protection or the + * expected header protection height. */ - int getPeripheralProtectionHeight() { + int getPeripheralProtectionHeight(boolean expected) { + if (expected) { + return getTabLayout().getBottom() - getPaddingTop() + getPaddingBottom() + - mMaxTranslation; + } // we only want to show protection when work tab is available and header is either // collapsed or animating to/from collapsed state if (mTabsHidden || mFloatingRowsCollapsed || !mHeaderCollapsed) { diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index be120cce75..a6a2f91513 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -509,9 +509,12 @@ public class PrivateProfileManager extends UserProfileManager { if (rowToExpandToWithRespectToHeader == -1) { rowToExpandToWithRespectToHeader = currentItem.rowIndex; } + // If there are no tabs, decrease the row to scroll to by 1 since the header + // may be cut off slightly. int rowToScrollTo = (int) Math.floor((double) (mAllApps.getHeight() - psHeaderHeight - - mAllApps.getHeaderProtectionHeight()) / allAppsCellHeight); + - mAllApps.getHeaderProtectionHeight()) / allAppsCellHeight) + - (mAllApps.isUsingTabs() ? 0 : 1); int currentRowDistance = currentItem.rowIndex - rowToExpandToWithRespectToHeader; // rowToScrollTo - 1 since the item to scroll to is 0 indexed. if (currentRowDistance == rowToScrollTo - 1) { diff --git a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java index 351b921e97..9363ce81c6 100644 --- a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java +++ b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java @@ -290,6 +290,7 @@ public class PrivateSpaceHeaderViewTest { doReturn(0).when(privateProfileManager).addSystemAppsDivider(any()); when(mAllApps.getHeight()).thenReturn(ALL_APPS_HEIGHT); when(mAllApps.getHeaderProtectionHeight()).thenReturn(HEADER_PROTECTION_HEIGHT); + when(mAllApps.isUsingTabs()).thenReturn(true); mAlphabeticalAppsList = new AlphabeticalAppsList<>(mContext, mAllAppsStore, null, privateProfileManager); mAlphabeticalAppsList.setNumAppsPerRowAllApps(NUM_APP_COLS); @@ -310,6 +311,43 @@ public class PrivateSpaceHeaderViewTest { ALL_APPS_CELL_HEIGHT)); } + @Test + public void scrollForViewToBeVisibleInContainer_withHeaderNoTabs() { + when(mAllAppsStore.getApps()).thenReturn(createAppInfoList()); + PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager); + when(privateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED); + when(privateProfileManager.splitIntoUserInstalledAndSystemApps()) + .thenReturn(iteminfo -> iteminfo.componentName == null + || !iteminfo.componentName.getPackageName() + .equals(CAMERA_PACKAGE_NAME)); + doReturn(0).when(privateProfileManager).addPrivateSpaceHeader(any()); + doAnswer(answer(this::addPrivateSpaceHeader)).when(privateProfileManager) + .addPrivateSpaceHeader(any()); + doNothing().when(privateProfileManager).addPrivateSpaceInstallAppButton(any()); + doReturn(0).when(privateProfileManager).addSystemAppsDivider(any()); + when(mAllApps.getHeight()).thenReturn(ALL_APPS_HEIGHT); + when(mAllApps.getHeaderProtectionHeight()).thenReturn(HEADER_PROTECTION_HEIGHT); + when(mAllApps.isUsingTabs()).thenReturn(false); + mAlphabeticalAppsList = new AlphabeticalAppsList<>(mContext, mAllAppsStore, + null, privateProfileManager); + mAlphabeticalAppsList.setNumAppsPerRowAllApps(NUM_APP_COLS); + mAlphabeticalAppsList.updateItemFilter(info -> info != null + && info.user.equals(MAIN_HANDLE)); + + int rows = (int) (ALL_APPS_HEIGHT - PS_HEADER_HEIGHT - HEADER_PROTECTION_HEIGHT) - 1; + int position = rows * NUM_APP_COLS - (NUM_APP_COLS-1) + 1; + + // The number of adapterItems should be the private space apps + one main app + header. + assertEquals(NUM_PRIVATE_SPACE_APPS + 1 + 1, + mAlphabeticalAppsList.getAdapterItems().size()); + assertEquals(position, + privateProfileManager.scrollForHeaderToBeVisibleInContainer( + new AllAppsRecyclerView(mContext), + mAlphabeticalAppsList.getAdapterItems(), + PS_HEADER_HEIGHT, + ALL_APPS_CELL_HEIGHT)); + } + @Test public void scrollForViewToBeVisibleInContainer_withHeaderAndLessAppRowSpace() { when(mAllAppsStore.getApps()).thenReturn(createAppInfoList()); @@ -325,6 +363,7 @@ public class PrivateSpaceHeaderViewTest { doNothing().when(privateProfileManager).addPrivateSpaceInstallAppButton(any()); doReturn(0).when(privateProfileManager).addSystemAppsDivider(any()); when(mAllApps.getHeight()).thenReturn(ALL_APPS_HEIGHT); + when(mAllApps.isUsingTabs()).thenReturn(true); when(mAllApps.getHeaderProtectionHeight()).thenReturn(HEADER_PROTECTION_HEIGHT); mAlphabeticalAppsList = new AlphabeticalAppsList<>(mContext, mAllAppsStore, null, privateProfileManager);