diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java index 747b755263..2f927d3142 100644 --- a/src/com/android/launcher3/FastScrollRecyclerView.java +++ b/src/com/android/launcher3/FastScrollRecyclerView.java @@ -24,7 +24,6 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.Nullable; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.compat.AccessibilityManagerCompat; @@ -92,8 +91,7 @@ public abstract class FastScrollRecyclerView extends RecyclerView { protected int getAvailableScrollHeight() { // AvailableScrollHeight = Total height of the all items - first page height int firstPageHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - int totalHeightOfAllItems = getItemsHeight(/* untilIndex= */ getAdapter().getItemCount()); - int availableScrollHeight = totalHeightOfAllItems - firstPageHeight; + int availableScrollHeight = computeVerticalScrollRange() - firstPageHeight; return Math.max(0, availableScrollHeight); } @@ -146,10 +144,7 @@ public abstract class FastScrollRecyclerView extends RecyclerView { // IF scroller is at the very top OR there is no scroll bar because there is probably not // enough items to scroll, THEN it's okay for the container to be pulled down. - if (getCurrentScrollY() == 0) { - return true; - } - return getAdapter() == null || getAdapter().getItemCount() == 0; + return computeVerticalScrollOffset() == 0; } /** @@ -159,53 +154,6 @@ public abstract class FastScrollRecyclerView extends RecyclerView { return true; } - /** - * @return the scroll top of this recycler view. - */ - public int getCurrentScrollY() { - Adapter adapter = getAdapter(); - if (adapter == null) { - return -1; - } - if (adapter.getItemCount() == 0 || getChildCount() == 0) { - return -1; - } - - int itemPosition = NO_POSITION; - View child = null; - - LayoutManager layoutManager = getLayoutManager(); - if (layoutManager instanceof LinearLayoutManager) { - // Use the LayoutManager as the source of truth for visible positions. During - // animations, the view group child may not correspond to the visible views that appear - // at the top. - itemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); - child = layoutManager.findViewByPosition(itemPosition); - } - - if (child == null) { - // If the layout manager returns null for any reason, which can happen before layout - // has occurred for the position, then look at the child of this view as a ViewGroup. - child = getChildAt(0); - itemPosition = getChildAdapterPosition(child); - } - if (itemPosition == NO_POSITION) { - return -1; - } - return getPaddingTop() + getItemsHeight(itemPosition) - - layoutManager.getDecoratedTop(child); - } - - /** - * Returns the sum of the height, in pixels, of this list adapter's items from index - * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, - * it returns the full height of all the items. - * - *

If the untilIndex is larger than the total number of items in this adapter, returns the - * sum of all items' height. - */ - protected abstract int getItemsHeight(int untilIndex); - /** * Maps the touch (from 0..1) to the adapter position that should be visible. *

Override in each subclass of this base class. diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3abefe0cad..07d0f55321 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2803,7 +2803,7 @@ public class Launcher extends StatefulActivity View v = getFirstMatch(Collections.singletonList(activeRecyclerView), preferredItem, packageAndUserAndApp); - if (v != null && activeRecyclerView.getCurrentScrollY() > 0) { + if (v != null && activeRecyclerView.computeVerticalScrollOffset() > 0) { RectF locationBounds = new RectF(); FloatingIconView.getLocationBoundsForView(this, v, false, locationBounds, new Rect()); diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index fe0230a837..368a37384d 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -26,7 +26,9 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.Adapter; +import com.android.launcher3.util.ScrollableLayoutManager; import com.android.launcher3.views.ActivityContext; import java.util.List; @@ -66,10 +68,10 @@ public class AllAppsGridAdapter extends /** * A subclass of GridLayoutManager that overrides accessibility values during app search. */ - public class AppsGridLayoutManager extends GridLayoutManager { + public class AppsGridLayoutManager extends ScrollableLayoutManager { public AppsGridLayoutManager(Context context) { - super(context, 1, GridLayoutManager.VERTICAL, false); + super(context); } @Override @@ -129,6 +131,15 @@ public class AllAppsGridAdapter extends } return extraRows; } + + @Override + protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { + AllAppsGridAdapter.AdapterItem item = mApps.getAdapterItems().get(position); + // only account for the first icon in the row since they are the same size within a row + return (isIconViewType(item.viewType) && item.rowAppIndex != 0) + ? heightUntilLastPos + : (heightUntilLastPos + mCachedSizes.get(item.viewType)); + } } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 0efa7c4444..ac10892ece 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.allapps; -import static android.view.View.MeasureSpec.UNSPECIFIED; - import static com.android.launcher3.logger.LauncherAtom.ContainerInfo; import static com.android.launcher3.logger.LauncherAtom.SearchResultContainer; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED_DOWN; @@ -30,7 +28,6 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; -import android.util.SparseIntArray; import androidx.recyclerview.widget.RecyclerView; @@ -54,41 +51,11 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { private static final boolean DEBUG = false; private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING); - protected AlphabeticalAppsList mApps; protected final int mNumAppsPerRow; - - // The specific view heights that we use to calculate scroll - private final SparseIntArray mViewHeights = new SparseIntArray(); - private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; private int mCumulativeVerticalScroll; - - private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { - public void onChanged() { - mCachedScrollPositions.clear(); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeRemoved(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { - onChanged(); - } - }; + protected AlphabeticalAppsList mApps; public AllAppsRecyclerView(Context context) { this(context, null); @@ -128,12 +95,8 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ALL_APPS_DIVIDER, 1); pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * (mNumAppsPerRow + 1)); - - mViewHeights.clear(); - mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, grid.allAppsCellHeightPx); } - @Override public void onDraw(Canvas c) { if (DEBUG) { @@ -212,17 +175,6 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { mFastScrollHelper.onFastScrollCompleted(); } - @Override - public void setAdapter(Adapter adapter) { - if (getAdapter() != null) { - getAdapter().unregisterAdapterDataObserver(mObserver); - } - super.setAdapter(adapter); - if (adapter != null) { - adapter.registerAdapterDataObserver(mObserver); - } - } - @Override protected boolean isPaddingOffsetRequired() { return true; @@ -244,13 +196,13 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { List items = mApps.getAdapterItems(); // Skip early if there are no items or we haven't been measured - if (items.isEmpty() || mNumAppsPerRow == 0) { + if (items.isEmpty() || mNumAppsPerRow == 0 || getChildCount() == 0) { mScrollbar.setThumbOffsetY(-1); return; } // Skip early if, there no child laid out in the container. - int scrollY = getCurrentScrollY(); + int scrollY = computeVerticalScrollOffset(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -305,51 +257,6 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { } } - @Override - protected int getItemsHeight(int position) { - List items = mApps.getAdapterItems(); - AllAppsGridAdapter.AdapterItem posItem = position < items.size() - ? items.get(position) : null; - int y = mCachedScrollPositions.get(position, -1); - if (y < 0) { - y = 0; - for (int i = 0; i < position; i++) { - AllAppsGridAdapter.AdapterItem item = items.get(i); - if (AllAppsGridAdapter.isIconViewType(item.viewType)) { - // Break once we reach the desired row - if (posItem != null && posItem.viewType == item.viewType && - posItem.rowIndex == item.rowIndex) { - break; - } - // Otherwise, only account for the first icon in the row since they are the same - // size within a row - if (item.rowAppIndex == 0) { - y += mViewHeights.get(item.viewType, 0); - } - } else { - // Rest of the views span the full width - int elHeight = mViewHeights.get(item.viewType); - if (elHeight == 0) { - ViewHolder holder = findViewHolderForAdapterPosition(i); - if (holder == null) { - holder = getAdapter().createViewHolder(this, item.viewType); - getAdapter().onBindViewHolder(holder, i); - holder.itemView.measure(UNSPECIFIED, UNSPECIFIED); - elHeight = holder.itemView.getMeasuredHeight(); - - getRecycledViewPool().putRecycledView(holder); - } else { - elHeight = holder.itemView.getMeasuredHeight(); - } - } - y += elHeight; - } - } - mCachedScrollPositions.put(position, y); - } - return y; - } - public int getScrollBarTop() { return getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding); } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 70c1e18301..7f6247e33e 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -106,7 +106,8 @@ public abstract class BaseAllAppsContainerView l.getAppsView().getActiveRecyclerView().getCurrentScrollY()); + l -> l.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset()); } case TestProtocol.REQUEST_WIDGETS_SCROLL_Y: { return getLauncherUIProperty(Bundle::putInt, - l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY()); + l -> WidgetsFullSheet.getWidgetsView(l).computeVerticalScrollOffset()); } case TestProtocol.REQUEST_TARGET_INSETS: { diff --git a/src/com/android/launcher3/util/ScrollableLayoutManager.java b/src/com/android/launcher3/util/ScrollableLayoutManager.java new file mode 100644 index 0000000000..17eaefda18 --- /dev/null +++ b/src/com/android/launcher3/util/ScrollableLayoutManager.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.util; + +import android.content.Context; +import android.util.SparseIntArray; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.Adapter; +import androidx.recyclerview.widget.RecyclerView.State; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; + +/** + * Extension of {@link GridLayoutManager} with support for smooth scrolling + */ +public class ScrollableLayoutManager extends GridLayoutManager { + + // keyed on item type + protected final SparseIntArray mCachedSizes = new SparseIntArray(); + + private RecyclerView mRv; + + /** + * Precalculated total height keyed on the item position. This is always incremental. + * Subclass can override {@link #incrementTotalHeight} to incorporate the layout logic. + * For example all-apps should have same values for items in same row, + * sample values: 0, 10, 10, 10, 10, 20, 20, 20, 20 + * whereas widgets will have strictly increasing values + * sample values: 0, 10, 50, 60, 110 + */ + + // + private int[] mTotalHeightCache = new int[1]; + private int mLastValidHeightIndex = 0; + + public ScrollableLayoutManager(Context context) { + super(context, 1, GridLayoutManager.VERTICAL, false); + } + + @Override + public void onAttachedToWindow(RecyclerView view) { + super.onAttachedToWindow(view); + mRv = view; + } + + @Override + public void layoutDecorated(@NonNull View child, int left, int top, int right, int bottom) { + super.layoutDecorated(child, left, top, right, bottom); + mCachedSizes.put( + mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); + } + + @Override + public void layoutDecoratedWithMargins(@NonNull View child, int left, int top, int right, + int bottom) { + super.layoutDecoratedWithMargins(child, left, top, right, bottom); + mCachedSizes.put( + mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); + } + + @Override + public int computeVerticalScrollExtent(State state) { + return mRv == null ? 0 : mRv.getHeight(); + } + + @Override + public int computeVerticalScrollOffset(State state) { + Adapter adapter = mRv == null ? null : mRv.getAdapter(); + if (adapter == null) { + return 0; + } + if (adapter.getItemCount() == 0 || getChildCount() == 0) { + return 0; + } + View child = getChildAt(0); + ViewHolder holder = mRv.findContainingViewHolder(child); + if (holder == null) { + return 0; + } + int itemPosition = holder.getLayoutPosition(); + if (itemPosition < 0) { + return 0; + } + return getPaddingTop() + getItemsHeight(adapter, itemPosition) - getDecoratedTop(child); + } + + @Override + public int computeVerticalScrollRange(State state) { + Adapter adapter = mRv == null ? null : mRv.getAdapter(); + return adapter == null ? 0 : getItemsHeight(adapter, adapter.getItemCount()); + } + + /** + * Returns the sum of the height, in pixels, of this list adapter's items from index + * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, + * it returns the full height of all the items. + * + *

If the untilIndex is larger than the total number of items in this adapter, returns the + * sum of all items' height. + */ + private int getItemsHeight(Adapter adapter, int untilIndex) { + final int totalItems = adapter.getItemCount(); + if (mTotalHeightCache.length < (totalItems + 1)) { + mTotalHeightCache = new int[totalItems + 1]; + mLastValidHeightIndex = 0; + } + if (untilIndex > totalItems) { + untilIndex = totalItems; + } else if (untilIndex < 0) { + untilIndex = 0; + } + if (untilIndex <= mLastValidHeightIndex) { + return mTotalHeightCache[untilIndex]; + } + + int totalItemsHeight = mTotalHeightCache[mLastValidHeightIndex]; + for (int i = mLastValidHeightIndex; i < untilIndex; i++) { + totalItemsHeight = incrementTotalHeight(adapter, i, totalItemsHeight); + mTotalHeightCache[i + 1] = totalItemsHeight; + } + mLastValidHeightIndex = untilIndex; + return totalItemsHeight; + } + + /** + * The current implementation assumes a linear list with every item taking up the whole row. + * Subclasses should override this method to account for any spanning logic + */ + protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { + return heightUntilLastPos + mCachedSizes.get(adapter.getItemViewType(position)); + } + + private void invalidateScrollCache() { + mLastValidHeightIndex = 0; + } + + @Override + public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) { + super.onItemsAdded(recyclerView, positionStart, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsChanged(RecyclerView recyclerView) { + super.onItemsChanged(recyclerView); + invalidateScrollCache(); + } + + @Override + public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) { + super.onItemsRemoved(recyclerView, positionStart, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) { + super.onItemsMoved(recyclerView, from, to, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount, + Object payload) { + super.onItemsUpdated(recyclerView, positionStart, itemCount, payload); + invalidateScrollCache(); + } +} diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java index 40e4ce1c04..3af2e3c9dc 100644 --- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java +++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java @@ -119,7 +119,6 @@ public class RecyclerViewFastScroller extends View { // prevent jumping, this offset is applied as the user scrolls. protected int mTouchOffsetY; protected int mThumbOffsetY; - protected int mRvOffsetY; // Fast scroller popup private TextView mPopupView; @@ -207,16 +206,11 @@ public class RecyclerViewFastScroller extends View { public void setThumbOffsetY(int y) { if (mThumbOffsetY == y) { - int rvCurrentOffsetY = mRv.getCurrentScrollY(); - if (mRvOffsetY != rvCurrentOffsetY) { - mRvOffsetY = mRv.getCurrentScrollY(); - } return; } updatePopupY(y); mThumbOffsetY = y; invalidate(); - mRvOffsetY = mRv.getCurrentScrollY(); } public int getThumbOffsetY() { diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java index 35fa7a42cc..5969e3e154 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java @@ -19,7 +19,6 @@ package com.android.launcher3.widget.picker; import android.content.Context; import android.graphics.Point; import android.util.AttributeSet; -import android.util.SparseIntArray; import android.view.MotionEvent; import androidx.recyclerview.widget.LinearLayoutManager; @@ -28,6 +27,7 @@ import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; import com.android.launcher3.FastScrollRecyclerView; import com.android.launcher3.R; +import com.android.launcher3.util.ScrollableLayoutManager; /** * The widgets recycler view. @@ -42,14 +42,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte private boolean mTouchDownOnScroller; private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider; - /** - * There is always 1 or 0 item of VIEW_TYPE_WIDGETS_LIST. Other types have fixes sizes, so the - * the size can be used for all other items of same type. Caching the last know size for - * VIEW_TYPE_WIDGETS_LIST allows us to use it to estimate full size even when - * VIEW_TYPE_WIDGETS_LIST is not visible on the screen. - */ - private final SparseIntArray mCachedSizes = new SparseIntArray(); - public WidgetsRecyclerView(Context context) { this(context, null); } @@ -68,9 +60,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte @Override protected void onFinishInflate() { super.onFinishInflate(); - // create a layout manager with Launcher's context so that scroll position - // can be preserved during screen rotation. - setLayoutManager(new LinearLayoutManager(getContext())); + setLayoutManager(new ScrollableLayoutManager(getContext())); } @Override @@ -114,7 +104,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte } // Skip early if, there no child laid out in the container. - int scrollY = getCurrentScrollY(); + int scrollY = computeVerticalScrollOffset(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -163,39 +153,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte mHeaderViewDimensionsProvider = headerViewDimensionsProvider; } - /** - * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until - * {@code untilIndex}. - * - *

If the untilIndex is larger than the total number of items in this adapter, returns the - * sum of all items' height. - */ - @Override - protected int getItemsHeight(int untilIndex) { - // Initialize cache - int childCount = getChildCount(); - int startPosition; - if (childCount > 0 - && ((startPosition = getChildAdapterPosition(getChildAt(0))) != NO_POSITION)) { - int loopCount = Math.min(getChildCount(), getAdapter().getItemCount() - startPosition); - for (int i = 0; i < loopCount; i++) { - mCachedSizes.put( - mAdapter.getItemViewType(startPosition + i), - getChildAt(i).getMeasuredHeight()); - } - } - - if (untilIndex > mAdapter.getItems().size()) { - untilIndex = mAdapter.getItems().size(); - } - int totalItemsHeight = 0; - for (int i = 0; i < untilIndex; i++) { - int type = mAdapter.getItemViewType(i); - totalItemsHeight += mCachedSizes.get(type); - } - return totalItemsHeight; - } - /** * Provides dimensions of the header view that is shown at the top of a * {@link WidgetsRecyclerView}. diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 32b62fb317..70d122bc90 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -537,7 +537,7 @@ public abstract class AbstractLauncherUiTest { } protected int getAllAppsScroll(Launcher launcher) { - return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY(); + return launcher.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset(); } private void checkLauncherIntegrity( diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index a3eee00c51..cf5f5fc320 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -302,7 +302,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } private int getWidgetsScroll(Launcher launcher) { - return getWidgetsView(launcher).getCurrentScrollY(); + return getWidgetsView(launcher).computeVerticalScrollOffset(); } private boolean isOptionsPopupVisible(Launcher launcher) {