Is there a callback for when RecyclerView has finished showing its items after I’ve set it with an adapter?

I’ve found a way to solve this (thanks to user pskink), by using the callback of LayoutManager:

final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false) {
    @Override
    public void onLayoutChildren(final Recycler recycler, final State state) {
        super.onLayoutChildren(recycler, state);
        //TODO if the items are filtered, considered hiding the fast scroller here
        final int firstVisibleItemPosition = findFirstVisibleItemPosition();
        if (firstVisibleItemPosition != 0) {
            // this avoids trying to handle un-needed calls
            if (firstVisibleItemPosition == -1)
                //not initialized, or no items shown, so hide fast-scroller
                mFastScroller.setVisibility(View.GONE);
            return;
        }
        final int lastVisibleItemPosition = findLastVisibleItemPosition();
        int itemsShown = lastVisibleItemPosition - firstVisibleItemPosition + 1;
        //if all items are shown, hide the fast-scroller
        mFastScroller.setVisibility(mAdapter.getItemCount() > itemsShown ? View.VISIBLE : View.GONE);
    }
};

The good thing here is that it works well and will handle even keyboard being shown/hidden.

The bad thing is that it gets called on cases that aren’t interesting (meaning it has false positives), but it’s not as often as scrolling events, so it’s good enough for me.


EDIT: there is a better callback that was added later, which doesn’t get called multiple times. Here’s the new code instead of what I wrote above:

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false) {
    @Override
    public void onLayoutCompleted(final State state) {
        super.onLayoutCompleted(state);
        final int firstVisibleItemPosition = findFirstVisibleItemPosition();
        final int lastVisibleItemPosition = findLastVisibleItemPosition();
        int itemsShown = lastVisibleItemPosition - firstVisibleItemPosition + 1;
        //if all items are shown, hide the fast-scroller
        fastScroller.setVisibility(adapter.getItemCount() > itemsShown ? View.VISIBLE : View.GONE);
    }
});

Leave a Comment