From e416c76b7232d82a4e0762fa52369d5b2baeefd8 Mon Sep 17 00:00:00 2001 From: maxli Date: Fri, 25 Oct 2024 17:46:41 +0800 Subject: [PATCH 1/3] fix(android): correct waterfall first and end item index in onScroll --- .../hippylist/HippyRecyclerListAdapter.java | 4 ++++ .../hippylist/RecyclerViewEventHelper.java | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerListAdapter.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerListAdapter.java index f603bf1f23b..7c0c14a9b2b 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerListAdapter.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerListAdapter.java @@ -183,6 +183,10 @@ public boolean hasPullHeader() { return headerRefreshHelper != null; } + public boolean hasPullFooter() { + return footerRefreshHelper != null; + } + public boolean hasBannerView() { ListItemRenderNode node; if (hasPullHeader()) { diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java index a5169be0f36..38e27a8f7f7 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java @@ -57,6 +57,7 @@ public class RecyclerViewEventHelper extends OnScrollListener implements OnLayoutChangeListener, OnAttachStateChangeListener, HippyOverPullListener { + private static final String TAG = "RecyclerViewEventHelper"; private static final int WATERFALL_SCROLL_RELAYOUT_THRESHOLD = 4; protected final HippyRecyclerView hippyRecyclerView; private boolean scrollBeginDragEventEnable; @@ -404,7 +405,6 @@ public HashMap generateWaterfallViewScrollEvent() { first = positions[i]; } } - scrollEvent.put("firstVisibleRowIndex", first); positions = layoutManager.findLastVisibleItemPositions(null); int end = positions[0]; for (int i = 0; i < positions.length; ++i) { @@ -412,6 +412,21 @@ public HashMap generateWaterfallViewScrollEvent() { end = positions[i]; } } + Adapter adapter = hippyRecyclerView.getAdapter(); + if (adapter instanceof HippyRecyclerListAdapter) { + HippyRecyclerListAdapter listAdapter = ((HippyRecyclerListAdapter) adapter); + int count = listAdapter.getItemCount(); + if (listAdapter.hasPullHeader()) { + first = Math.max(0, (first - 1)); + end = Math.max(0, (end - 1)); + count -= 1; + } + if (listAdapter.hasPullFooter() && (end == (count - 1))) { + end = Math.max(0, (end - 1)); + } + } + LogUtils.d(TAG, "generateWaterfallViewScrollEvent: first " + first + ", end " + end); + scrollEvent.put("firstVisibleRowIndex", first); scrollEvent.put("lastVisibleRowIndex", end); ArrayList rowFrames = new ArrayList<>(); int total = hippyRecyclerView.getChildCount(); From be53c3e041d2f58b1d369405cd3dd29f619b79d4 Mon Sep 17 00:00:00 2001 From: maxli Date: Wed, 30 Oct 2024 14:46:41 +0800 Subject: [PATCH 2/3] fix(android): end reach check failed when set preloadItemNumber --- .../src/components/WaterfallView/index.jsx | 2 +- .../mtt/hippy/views/hippylist/HippyRecyclerView.java | 3 +++ .../views/hippylist/RecyclerViewEventHelper.java | 12 ++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/driver/js/examples/hippy-react-demo/src/components/WaterfallView/index.jsx b/driver/js/examples/hippy-react-demo/src/components/WaterfallView/index.jsx index 4fd51526e5b..d6154fae2fd 100644 --- a/driver/js/examples/hippy-react-demo/src/components/WaterfallView/index.jsx +++ b/driver/js/examples/hippy-react-demo/src/components/WaterfallView/index.jsx @@ -358,7 +358,7 @@ export default class ListExample extends React.Component { interItemSpacing={interItemSpacing} numberOfItems={dataSource.length} contentInset={contentInset} - preloadItemNumber={4} + preloadItemNumber={12} style={{ flex: 1 }} onScroll={this.onScroll} renderBanner={this.renderBanner} diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java index 60e66bf913c..2ebe3dd3739 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/HippyRecyclerView.java @@ -275,6 +275,9 @@ public void setListData() { overPullHelper.enableOverPullUp(!listAdapter.hasFooter()); overPullHelper.enableOverPullDown(!listAdapter.hasHeader()); } + if (currentNodeCount > renderNodeCount) { + getRecyclerViewEventHelper().onListDataChanged(); + } renderNodeCount = currentNodeCount; if (renderNodeCount > 0 && mInitialContentOffset > 0) { scrollToInitContentOffset(); diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java index 38e27a8f7f7..a2d369a9e4c 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java @@ -80,7 +80,7 @@ public class RecyclerViewEventHelper extends OnScrollListener implements OnLayou private boolean isInitialListReadyNotified = false; private ViewTreeObserver viewTreeObserver; private OnPreDrawListener preDrawListener; - private boolean isLastTimeReachEnd; + private boolean hasEndReached = false; private int preloadItemNumber; private Rect reusableExposureStateRect = new Rect(); @@ -226,6 +226,10 @@ protected boolean scrollHappened(int dx, int dy) { return dx != 0 || dy != 0; } + public void onListDataChanged() { + hasEndReached = false; + } + /** * 检查是否已经触底,发生onEndReached事件给前端 如果上次是没有到底,这次滑动底了,需要发事件通知,如果上一次已经是到底了,这次到底不会发事件 */ @@ -236,10 +240,10 @@ private void checkSendReachEndEvent() { } else { isThisTimeReachEnd = isVerticalReachEnd(); } - if (!isLastTimeReachEnd && isThisTimeReachEnd) { + if (!hasEndReached && isThisTimeReachEnd) { sendOnReachedEvent(); } - isLastTimeReachEnd = isThisTimeReachEnd; + hasEndReached = isThisTimeReachEnd; } private int findLastVisibleItemMaxPosition() { @@ -296,6 +300,7 @@ private boolean isHorizontalReachEnd() { } protected void sendOnReachedEvent() { + LogUtils.d(TAG, "sendOnReachedEvent: "); EventUtils.sendComponentEvent(getParentView(), EventUtils.EVENT_RECYCLER_END_REACHED, null); EventUtils.sendComponentEvent(getParentView(), EventUtils.EVENT_RECYCLER_LOAD_MORE, null); } @@ -425,7 +430,6 @@ public HashMap generateWaterfallViewScrollEvent() { end = Math.max(0, (end - 1)); } } - LogUtils.d(TAG, "generateWaterfallViewScrollEvent: first " + first + ", end " + end); scrollEvent.put("firstVisibleRowIndex", first); scrollEvent.put("lastVisibleRowIndex", end); ArrayList rowFrames = new ArrayList<>(); From 2b4c2a4532e59710576a55f07223ec1c5c7328cd Mon Sep 17 00:00:00 2001 From: maxli Date: Wed, 30 Oct 2024 18:05:18 +0800 Subject: [PATCH 3/3] fix(android): add comments for waterfall onScroll event params --- .../hippy/views/hippylist/RecyclerViewEventHelper.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java index a2d369a9e4c..a7345aab68f 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/hippylist/RecyclerViewEventHelper.java @@ -186,7 +186,8 @@ private void relayoutWaterfallIfNeeded() { LayoutManager layoutManager = hippyRecyclerView.getLayoutManager(); if (layoutManager instanceof HippyStaggeredGridLayoutManager) { int[] firstVisibleItem = null; - firstVisibleItem = ((HippyStaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(firstVisibleItem); + firstVisibleItem = ((HippyStaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions( + firstVisibleItem); if (firstVisibleItem != null && (firstVisibleItem[0] <= WATERFALL_SCROLL_RELAYOUT_THRESHOLD)) { Adapter adapter = hippyRecyclerView.getAdapter(); if (adapter != null) { @@ -421,11 +422,16 @@ public HashMap generateWaterfallViewScrollEvent() { if (adapter instanceof HippyRecyclerListAdapter) { HippyRecyclerListAdapter listAdapter = ((HippyRecyclerListAdapter) adapter); int count = listAdapter.getItemCount(); + // Android includes a pull header and a pull footer when calculating the position of an item. In order to + // align with iOS, if a pull header is included, the first item and last item position needs to be + // subtracted by 1 if (listAdapter.hasPullHeader()) { first = Math.max(0, (first - 1)); end = Math.max(0, (end - 1)); count -= 1; } + // For align with iOS, if a pull footer is included, the last item position needs to be + // subtracted by 1 if (listAdapter.hasPullFooter() && (end == (count - 1))) { end = Math.max(0, (end - 1)); }