Reland "Fix spacing and header protection for All Apps" after QPR1 merge

* Ensure that the expected header height is recalculated before/after
  search or orientation change. Otherwise, personal/work tabs will have
  different spacing behavior after these things occur; they will stick
  to the very edge of the search bar when scrolling down, with little
  to no spacing in between.
* Stabilize personal/work tabs when scrolling down. To do this, we do
  not add padding for floating header rows when we have no such rows.
* Various spacing adjustments in res/values/dimens.xml.

Test: Manual: Check consistent behavior of spacing and drawn header
rectangles in different conditions that are affected by this change:
1. Apps: Many installed (scrollable), and few (not scrollable).
2. Work profile: With and without one.
3. Search results.
4. Font size settings, smaller and larger.
5. (No known impact) Display size settings, smaller and larger.
6. Home screen rotation enabled, in landscape and portrait.

Issue: calyxos#1260
Original-Change-Id: I5cbf47eb4a734e9ce9b42d8ef9a27a167d614da0
Change-Id: I586f73325cecefcbed3a67f311710d1c8abffb85
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 47584e2..3bd66a9 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -107,14 +107,15 @@
     <!-- all_apps_search_bar_field_height / 2 -->
     <dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
     <dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
+    <dimen name="all_apps_search_bar_bottom_margin">6dp</dimen>
     <dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
     <dimen name="all_apps_header_pill_height">48dp</dimen>
     <dimen name="all_apps_header_pill_corner_radius">12dp</dimen>
     <dimen name="all_apps_header_tab_height">48dp</dimen>
     <dimen name="all_apps_tabs_indicator_height">2dp</dimen>
-    <dimen name="all_apps_header_top_margin">33dp</dimen>
+    <dimen name="all_apps_header_top_margin">40dp</dimen>
     <dimen name="all_apps_header_top_padding">36dp</dimen>
-    <dimen name="all_apps_header_bottom_padding">14dp</dimen>
+    <dimen name="all_apps_header_bottom_padding">10dp</dimen>
     <dimen name="all_apps_header_top_adjustment">6dp</dimen>
     <dimen name="all_apps_header_bottom_adjustment">4dp</dimen>
     <dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 2557a6c..e5bc18a 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -282,13 +282,15 @@
         }
 
         RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
-        layoutParams.addRule(RelativeLayout.ALIGN_TOP, R.id.search_container_all_apps);
+        layoutParams.addRule(RelativeLayout.BELOW, R.id.search_container_all_apps);
 
-        int topMargin = getContext().getResources().getDimensionPixelSize(
-                R.dimen.all_apps_header_top_margin);
+        int topMargin = -getContext().getResources().getDimensionPixelSize(
+                R.dimen.all_apps_search_bar_bottom_margin);
         if (includeTabsMargin) {
             topMargin += getContext().getResources().getDimensionPixelSize(
-                    R.dimen.all_apps_header_pill_height);
+                    R.dimen.all_apps_header_pill_height)
+                    + getContext().getResources().getDimensionPixelSize(
+                    R.dimen.all_apps_tabs_margin_top);
         }
         layoutParams.topMargin = topMargin;
     }
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index f082542..d1dacf6 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -89,6 +89,7 @@
     public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
 
     // Render the header protection at all times to debug clipping issues.
+    // This is useful enough to warrant the comment you are reading now to point it out!
     private static final boolean DEBUG_HEADER_PROTECTION = false;
 
     private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -666,8 +667,10 @@
                 getCurrentPage(),
                 tabsHidden);
 
-        int padding = mHeader.getMaxTranslation();
         mAH.forEach(adapterHolder -> {
+            final boolean tabsAlwaysHidden =
+                    adapterHolder.mRecyclerView instanceof SearchRecyclerView;
+            final int padding = mHeader.getTabsPadding(tabsAlwaysHidden);
             adapterHolder.mPadding.top = padding;
             adapterHolder.applyPadding();
             if (adapterHolder.mRecyclerView != null) {
@@ -751,7 +754,9 @@
                 } else {
                     mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
                 }
-                canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint);
+                final int protectionBottom = headerView.getBottom()
+                        - headerView.getTabsAdditionalPaddingTop();
+                canvas.drawRect(0, bottom, canvas.getWidth(), protectionBottom, mHeaderPaint);
             }
         }
     }
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 1cbb0f9..f85b9cb 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -99,6 +99,7 @@
 
     protected boolean mTabsHidden;
     protected int mMaxTranslation;
+    protected int mTabsPadding;
 
     // Whether the header has been scrolled off-screen.
     private boolean mHeaderCollapsed;
@@ -262,6 +263,8 @@
                 rvType == AdapterHolder.MAIN ? mMainRV
                 : rvType == AdapterHolder.WORK ? mWorkRV : mSearchRV;
         mCurrentRV.addOnScrollListener(mOnScrollListener);
+
+        updateExpectedHeight();
     }
 
     private void updateExpectedHeight() {
@@ -272,8 +275,26 @@
         }
         mMaxTranslation += mFloatingRowsHeight;
         if (!mTabsHidden) {
-            mMaxTranslation += mTabsAdditionalPaddingBottom
+            mTabsPadding = mTabsAdditionalPaddingBottom
                     + getResources().getDimensionPixelSize(R.dimen.all_apps_tabs_margin_top);
+            // We don't need to add the padding for floating rows if there aren't any.
+            // Doing so causes the personal/work tabs to shift unnecessarily when scrolling.
+            if (mFloatingRowsHeight > 0) {
+                mMaxTranslation += mTabsPadding;
+            }
+        }
+    }
+
+    int getTabsPadding(boolean tabsAlwaysHidden) {
+        final boolean tabsHidden = tabsAlwaysHidden || mTabsHidden;
+        if (!tabsHidden && mFloatingRowsHeight == 0) {
+            return 0;
+        } else if (mTabsPadding == 0 && (tabsHidden || mFloatingRowsCollapsed)) {
+            return getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_bottom_padding);
+        } else if (mTabsPadding > 0 && tabsHidden) {
+            return mTabsPadding + getPaddingTop();
+        } else {
+            return mTabsPadding;
         }
     }