Revert "Updating the scroll calculation from recyclerView to avoid view inflation"
This reverts commit 20bbe95ddbe0d93a50e18aba4623cc844ecfb9e5.
Reason for revert: Causing flake in Ironwood test: b/248295569
Test: ABTD
Before: Flaky, 14/50 PASSED
https://android-build.googleplex.com/builds/abtd/run/L33900000956890639
Revert: 50/50 PASSED
https://android-build.googleplex.com/builds/abtd/run/L49200000956887317
Change-Id: I41f4428c74e581323f90c716a7852b5e553ae27d
diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java
index 2f927d3..747b755 100644
--- a/src/com/android/launcher3/FastScrollRecyclerView.java
+++ b/src/com/android/launcher3/FastScrollRecyclerView.java
@@ -24,6 +24,7 @@
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;
@@ -91,7 +92,8 @@
protected int getAvailableScrollHeight() {
// AvailableScrollHeight = Total height of the all items - first page height
int firstPageHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
- int availableScrollHeight = computeVerticalScrollRange() - firstPageHeight;
+ int totalHeightOfAllItems = getItemsHeight(/* untilIndex= */ getAdapter().getItemCount());
+ int availableScrollHeight = totalHeightOfAllItems - firstPageHeight;
return Math.max(0, availableScrollHeight);
}
@@ -144,7 +146,10 @@
// 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.
- return computeVerticalScrollOffset() == 0;
+ if (getCurrentScrollY() == 0) {
+ return true;
+ }
+ return getAdapter() == null || getAdapter().getItemCount() == 0;
}
/**
@@ -155,6 +160,53 @@
}
/**
+ * @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.
+ *
+ * <p>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.
* <p>Override in each subclass of this base class.
*/