Skip to content

Bottom padded ScrollView/RecyclerView weird behaviour #87

@moisoni97

Description

@moisoni97

I notice that when a ScrollView has a bottom padding, the overscroll effect starts before the ScrollView reaches the end, resulting in a weird glitch where the view is overscrolled and then kinda snaps to reach the padding.

<ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:paddingBottom="140dp"
            android:scrollbars="none">

Also, this can be fixed if we trigger the overscroll effect only when the user has genuinely reached the end of the content, accounting for any padding.

@UiThread
public final class ScrollViewOverScrollHelper implements IOverScrollDecoratorAdapter {

    private final ScrollView mScrollView;
    private final View mContentView;

    public ScrollViewOverScrollHelper(@NonNull ScrollView scrollView) {
        mScrollView = scrollView;
        mContentView = scrollView.getChildAt(0);
    }

    @Override
    public View getView() {
        return mScrollView;
    }

    @Override
    public boolean isInAbsoluteStart() {
        return mScrollView.getScrollY() <= 0;
    }

    @Override
    public boolean isInAbsoluteEnd() {
        if (mContentView == null) {
            return true;
        }

        int scrollY = mScrollView.getScrollY();
        int contentHeight = mContentView.getHeight();
        int scrollViewHeight = mScrollView.getHeight();
        int paddingBottom = mScrollView.getPaddingBottom();

        return scrollY >= (contentHeight - scrollViewHeight + paddingBottom);
    }
}
ScrollView scrollView = findViewById(R.id.scroll_view);
new VerticalOverScrollBounceEffectDecorator(new PaddedScrollViewOverScrollDecorAdapter(scrollView));

And similarly for RecyclerView. Unlike the ScrollView, it does not have any weird behaviour if it has a big bottom padding, but doesn't overscroll at all from bottom to top (if there are not enough items to fill the screen).

@UiThread
public final class RecyclerViewOverScrollHelper implements IOverScrollDecoratorAdapter {

    private final RecyclerView mRecyclerView;
    private final LinearLayoutManager mLayoutManager;

    public RecyclerViewOverScrollHelper(@NonNull RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
        mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
    }

    @Override
    public View getView() {
        return mRecyclerView;
    }

    @Override
    public boolean isInAbsoluteStart() {
        if (mLayoutManager.getItemCount() == 0) return false;
        return mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0;
    }

    @Override
    public boolean isInAbsoluteEnd() {
        int totalItemCount = mLayoutManager.getItemCount();
        if (totalItemCount == 0) return false;
        int lastVisibleItemPosition = mLayoutManager.findLastCompletelyVisibleItemPosition();

        return lastVisibleItemPosition == totalItemCount - 1;
    }
}
RecyclerView recyclerView = findViewById(R.id.recycler_view);
new VerticalOverScrollBounceEffectDecorator(new RecyclerViewOverScrollHelper(recyclerView));

I think this should be added in a future release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions