Fixes for fast-scrollbar when using work profile tabs in all apps.
- do not hide scrollbar between switching tabs
- full scrollbar height
- show predictionrow only when fully scrolled to top
Bug: 70037972
Bug: 68713881
Change-Id: Icaa434ce2726b75d22ec4ac3287ab2b0e18ce42b
diff --git a/res/layout-land/all_apps_fast_scroller.xml b/res/layout-land/all_apps_fast_scroller.xml
index 6a68f84..16aa2af 100644
--- a/res/layout-land/all_apps_fast_scroller.xml
+++ b/res/layout-land/all_apps_fast_scroller.xml
@@ -21,7 +21,7 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginTop="-5dp"
android:layout_marginEnd="-45dp" />
@@ -31,7 +31,7 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
- android:layout_alignParentTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="-88dp"
android:layout_marginTop="14dp"
launcher:canThumbDetach="true" />
diff --git a/res/layout-sw720dp/all_apps_fast_scroller.xml b/res/layout-sw720dp/all_apps_fast_scroller.xml
index 12c15cc..5537bc6 100644
--- a/res/layout-sw720dp/all_apps_fast_scroller.xml
+++ b/res/layout-sw720dp/all_apps_fast_scroller.xml
@@ -21,7 +21,7 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
<com.android.launcher3.views.RecyclerViewFastScroller
@@ -30,7 +30,7 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_end_margin"
launcher:canThumbDetach="true" />
diff --git a/res/layout/all_apps_fast_scroller.xml b/res/layout/all_apps_fast_scroller.xml
index 12c15cc..5537bc6 100644
--- a/res/layout/all_apps_fast_scroller.xml
+++ b/res/layout/all_apps_fast_scroller.xml
@@ -21,7 +21,7 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
<com.android.launcher3.views.RecyclerViewFastScroller
@@ -30,7 +30,7 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_end_margin"
launcher:canThumbDetach="true" />
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index b315980..bce0e2e 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -68,6 +68,7 @@
ViewGroup parent = (ViewGroup) getParent().getParent();
mScrollbar = parent.findViewById(R.id.fast_scroller);
mScrollbar.setRecyclerView(this, parent.findViewById(R.id.fast_scroller_popup));
+ onUpdateScrollbar(0);
}
/**
@@ -112,7 +113,7 @@
* Returns the height of the fast scroll bar
*/
public int getScrollbarTrackHeight() {
- return getHeight() - getScrollBarTop() - getPaddingBottom();
+ return mScrollbar.getHeight() - getScrollBarTop() - getPaddingBottom();
}
/**
@@ -130,12 +131,6 @@
return availableScrollBarHeight;
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- onUpdateScrollbar(0);
- super.dispatchDraw(canvas);
- }
-
/**
* Updates the scrollbar thumb offset to match the visible scroll of the recycler view. It does
* this by mapping the available scroll area of the recycler view to the available space for the
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 9ee9514..097bc5b 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -492,19 +492,9 @@
mViewPager.setAdapter(mTabsPagerAdapter = new TabsPagerAdapter());
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- boolean mVisible = true;
-
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
tabs.updateIndicatorPosition(position, positionOffset);
- if (positionOffset == 0 && !mVisible || positionOffset > 0 && mVisible) {
- mVisible = positionOffset == 0;
- for (int i = 0; i < mAH.length; i++) {
- if (mAH[i].recyclerView != null) {
- mAH[i].recyclerView.getScrollbar().setAlpha(mVisible ? 1 : 0);
- }
- }
- }
}
@Override
@@ -521,6 +511,7 @@
public void onPageScrollStateChanged(int state) {
}
});
+ mAH[AdapterHolder.MAIN].recyclerView.bindFastScrollbar();
findViewById(R.id.tab_personal)
.setOnClickListener((View view) -> mViewPager.setCurrentItem(0));
@@ -568,8 +559,8 @@
contentHeight += getResources()
.getDimensionPixelSize(R.dimen.all_apps_prediction_row_divider_height);
}
- RecyclerView mainRV = mAH[AdapterHolder.MAIN].recyclerView;
- RecyclerView workRV = mAH[AdapterHolder.WORK].recyclerView;
+ AllAppsRecyclerView mainRV = mAH[AdapterHolder.MAIN].recyclerView;
+ AllAppsRecyclerView workRV = mAH[AdapterHolder.WORK].recyclerView;
mFloatingHeaderHandler.setup(mainRV, workRV, contentHeight);
mFloatingHeaderHandler.getContentView().setup(mAH[AdapterHolder.MAIN].adapter,
mComponentToAppMap, mNumPredictedAppsPerRow);
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 5789b67..fd80784 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -31,7 +31,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.anim.SpringAnimationHandler;
import com.android.launcher3.config.FeatureFlags;
@@ -53,7 +52,6 @@
private AlphabeticalAppsList mApps;
private AllAppsFastScrollHelper mFastScrollHelper;
private int mNumAppsPerRow;
- private int mUserProfileTabContentHeight;
// The specific view heights that we use to calculate scroll
private SparseIntArray mViewHeights = new SparseIntArray();
@@ -127,8 +125,6 @@
public void setApps(AlphabeticalAppsList apps, boolean usingTabs) {
mApps = apps;
mFastScrollHelper = new AllAppsFastScrollHelper(this, apps);
- mUserProfileTabContentHeight = usingTabs
- ? Launcher.getLauncher(getContext()).getDeviceProfile().allAppsCellHeightPx : 0;;
}
public AlphabeticalAppsList getApps() {
@@ -362,6 +358,9 @@
*/
@Override
public void onUpdateScrollbar(int dy) {
+ if (mApps == null) {
+ return;
+ }
List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
// Skip early if there are no items or we haven't been measured
@@ -488,18 +487,11 @@
@Override
protected int getAvailableScrollHeight() {
return getPaddingTop() + getCurrentScrollY(getAdapter().getItemCount(), 0)
- - getHeight() + getPaddingBottom() + mUserProfileTabContentHeight;
+ - getHeight() + getPaddingBottom();
}
public int getScrollBarTop() {
- return super.getScrollBarTop() + mUserProfileTabContentHeight;
- }
-
- /**
- * Returns the height of the fast scroll bar
- */
- public int getScrollbarTrackHeight() {
- return super.getScrollbarTrackHeight() + mUserProfileTabContentHeight;
+ return getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding);
}
public RecyclerViewFastScroller getScrollbar() {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderHandler.java b/src/com/android/launcher3/allapps/FloatingHeaderHandler.java
index c4b533b..b4685ea 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderHandler.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderHandler.java
@@ -30,6 +30,8 @@
public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
implements ValueAnimator.AnimatorUpdateListener {
+ private static final boolean SHOW_PREDICTIONS_ONLY_ON_TOP = true;
+
private final View mHeaderView;
private final PredictionRowView mPredictionRow;
private final ViewGroup mTabLayout;
@@ -37,8 +39,8 @@
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
- private RecyclerView mMainRV;
- private RecyclerView mWorkRV;
+ private AllAppsRecyclerView mMainRV;
+ private AllAppsRecyclerView mWorkRV;
private boolean mTopOnlyMode;
private boolean mHeaderHidden;
private int mMaxTranslation;
@@ -55,22 +57,25 @@
mPredictionRow = header.findViewById(R.id.header_content);
}
- public void setup(@NonNull RecyclerView personalRV, @Nullable RecyclerView workRV,
+ public void setup(@NonNull AllAppsRecyclerView personalRV, @Nullable AllAppsRecyclerView workRV,
int predictionRowHeight) {
mTopOnlyMode = workRV == null;
mTabLayout.setVisibility(mTopOnlyMode ? View.GONE : View.VISIBLE);
mPredictionRow.getLayoutParams().height = predictionRowHeight;
mMaxTranslation = predictionRowHeight;
- mMainRV = personalRV;
- mMainRV.addOnScrollListener(this);
- mWorkRV = workRV;
- if (workRV != null) {
- workRV.addOnScrollListener(this);
- }
+ mMainRV = setupRV(mMainRV, personalRV);
+ mWorkRV = setupRV(mWorkRV, workRV);
setMainActive(true);
setupDivider();
}
+ private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
+ if (old != updated && updated != null ) {
+ updated.addOnScrollListener(this);
+ }
+ return updated;
+ }
+
private void setupDivider() {
Resources res = mHeaderView.getResources();
int verticalGap = res.getDimensionPixelSize(R.dimen.all_apps_divider_margin_vertical);
@@ -115,10 +120,9 @@
mAnimator.cancel();
}
- int current = isMainRV
- ? (mMainScrolledY -= dy)
- : (mWorkScrolledY -= dy);
-
+ int current = - (isMainRV
+ ? mMainRV.getCurrentScrollY()
+ : mWorkRV.getCurrentScrollY());
moved(current);
apply();
}
@@ -130,7 +134,8 @@
}
private boolean canSnapAt(int currentScrollY) {
- return !mTopOnlyMode || Math.abs(currentScrollY) <= mPredictionRow.getHeight();
+ boolean snapOnlyOnTop = SHOW_PREDICTIONS_ONLY_ON_TOP || mTopOnlyMode;
+ return !snapOnlyOnTop || Math.abs(currentScrollY) <= mPredictionRow.getHeight();
}
private void moved(final int currentScrollY) {
@@ -179,6 +184,9 @@
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ if (SHOW_PREDICTIONS_ONLY_ON_TOP) {
+ return;
+ }
if (!mTopOnlyMode && newState == RecyclerView.SCROLL_STATE_IDLE
&& mTranslationY != -mMaxTranslation && mTranslationY != 0) {
float scroll = Math.abs(getCurrentScroll());
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 8f20a8d..b36a0ff 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -141,10 +141,11 @@
}
public void setRecyclerView(BaseRecyclerView rv, TextView popupView) {
- mRv = rv;
- if (mOnScrollListener != null) {
+ if (mRv != null && mOnScrollListener != null) {
mRv.removeOnScrollListener(mOnScrollListener);
}
+ mRv = rv;
+
mRv.addOnScrollListener(mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {