Skip to content

Commit

Permalink
New method smoothScrollToPosition, to safely scroll to a position wit…
Browse files Browse the repository at this point in the history
…h a default delay of 150ms.
  • Loading branch information
davideas committed Jun 2, 2018
1 parent 99f1325 commit efd3a2a
Showing 1 changed file with 29 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1062,8 +1062,9 @@ public final void addScrollableHeaderWithDelay(@NonNull final T headerItem, @Int
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (addScrollableHeader(headerItem) && scrollToPosition)
performScroll(getGlobalPositionOf(headerItem));
if (addScrollableHeader(headerItem) && scrollToPosition) {
smoothScrollToPosition(getGlobalPositionOf(headerItem));
}
}
}, delay);
}
Expand All @@ -1084,8 +1085,9 @@ public final void addScrollableFooterWithDelay(@NonNull final T footerItem, @Int
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (addScrollableFooter(footerItem) && scrollToPosition)
performScroll(getGlobalPositionOf(footerItem));
if (addScrollableFooter(footerItem) && scrollToPosition) {
smoothScrollToPosition(getGlobalPositionOf(footerItem));
}
}
}, delay);
}
Expand Down Expand Up @@ -2879,7 +2881,7 @@ public void addItemWithDelay(@IntRange(from = 0) final int position, @NonNull fi
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (addItem(position, item) && scrollToPosition) performScroll(position);
if (addItem(position, item) && scrollToPosition) autoScrollWithDelay(position, -1);
}
}, delay);
}
Expand Down Expand Up @@ -3295,8 +3297,8 @@ private void performRemove(T item, boolean permanent) {
* Removes all items of a section, header included.
* <p>For header that is also expandable, it's equivalent to remove a single item.</p>
*
* @see #removeItem(int)
* @param header the head of the section
* @see #removeItem(int)
* @since 5.0.5
*/
public void removeSection(IHeader header) {
Expand Down Expand Up @@ -4955,22 +4957,40 @@ private boolean hasSubItemsSelected(int startPosition, List<T> subItems) {
return false;
}

/**
* Performs <i>safe</i> smooth scroll with a delay of {@value #AUTO_SCROLL_DELAY} ms.
*
* @param position the position to scroll to.
* @since 5.0.5
*/
public void smoothScrollToPosition(final int position) {
if (mRecyclerView != null) {
// Must be delayed to give time at RecyclerView to recalculate positions after a layout change
mRecyclerView.postDelayed(new Runnable() {
@Override
public void run() {
performScroll(position);
}
}, AUTO_SCROLL_DELAY);
}
}

private void performScroll(final int position) {
if (mRecyclerView != null) {
mRecyclerView.smoothScrollToPosition(Math.min(Math.max(0, position), getItemCount() - 1));
}
}

private void autoScrollWithDelay(final int position, final int subItemsCount) {
// Must be delayed to give time at RecyclerView to recalculate positions after an automatic collapse
// Must be delayed to give time at RecyclerView to recalculate positions after a layout change
new Handler(Looper.getMainLooper(), new Handler.Callback() {
public boolean handleMessage(Message message) {
// #492 - NullPointerException when expanding item with auto-scroll
if (mRecyclerView == null) return false;
int firstVisibleItem = getFlexibleLayoutManager().findFirstCompletelyVisibleItemPosition();
int lastVisibleItem = getFlexibleLayoutManager().findLastCompletelyVisibleItemPosition();
int itemsToShow = position + subItemsCount - lastVisibleItem;
// log.v("autoScroll itemsToShow=%s firstVisibleItem=%s lastVisibleItem=%s RvChildCount=%s", itemsToShow, firstVisibleItem, lastVisibleItem, mRecyclerView.getChildCount());
// log.v("autoScroll itemsToShow=%s firstVisibleItem=%s lastVisibleItem=%s RvChildCount=%s", itemsToShow, firstVisibleItem, lastVisibleItem, mRecyclerView.getChildCount());
if (itemsToShow > 0) {
int scrollMax = position - firstVisibleItem;
int scrollMin = Math.max(0, position + subItemsCount - lastVisibleItem);
Expand All @@ -4980,7 +5000,7 @@ public boolean handleMessage(Message message) {
scrollBy = scrollBy % spanCount + spanCount;
}
int scrollTo = firstVisibleItem + scrollBy;
// log.v("autoScroll scrollMin=%s scrollMax=%s scrollBy=%s scrollTo=%s", scrollMin, scrollMax, scrollBy, scrollTo);
// log.v("autoScroll scrollMin=%s scrollMax=%s scrollBy=%s scrollTo=%s", scrollMin, scrollMax, scrollBy, scrollTo);
performScroll(scrollTo);
} else if (position < firstVisibleItem) {
performScroll(position);
Expand Down

0 comments on commit efd3a2a

Please sign in to comment.