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
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ public abstract class BaseRecyclerView extends RecyclerView
|
||||
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 @@ public abstract class BaseRecyclerView extends RecyclerView
|
||||
* Returns the height of the fast scroll bar
|
||||
*/
|
||||
public int getScrollbarTrackHeight() {
|
||||
return getHeight() - getScrollBarTop() - getPaddingBottom();
|
||||
return mScrollbar.getHeight() - getScrollBarTop() - getPaddingBottom();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,12 +131,6 @@ public abstract class BaseRecyclerView extends RecyclerView
|
||||
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
|
||||
|
||||
@@ -492,19 +492,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
|
||||
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 class AllAppsContainerView extends RelativeLayout implements DragSource,
|
||||
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 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
|
||||
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);
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.android.launcher3.BaseRecyclerView;
|
||||
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 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
|
||||
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 class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
|
||||
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 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
|
||||
*/
|
||||
@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 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
|
||||
@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() {
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.android.launcher3.R;
|
||||
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 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
|
||||
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 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
|
||||
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 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
|
||||
mAnimator.cancel();
|
||||
}
|
||||
|
||||
int current = isMainRV
|
||||
? (mMainScrolledY -= dy)
|
||||
: (mWorkScrolledY -= dy);
|
||||
|
||||
int current = - (isMainRV
|
||||
? mMainRV.getCurrentScrollY()
|
||||
: mWorkRV.getCurrentScrollY());
|
||||
moved(current);
|
||||
apply();
|
||||
}
|
||||
@@ -130,7 +134,8 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
|
||||
}
|
||||
|
||||
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 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener
|
||||
|
||||
@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());
|
||||
|
||||
@@ -141,10 +141,11 @@ public class RecyclerViewFastScroller extends View {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user