How implement sticky footer in recyclerview Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How implement sticky footer in recyclerview without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I have RecyclerView and I need next behavior:

  • if there are a lot of items (more then fits screen) – footer is last item
  • if few item/no item – footer is located at screen bottom

Please advise how can I implement this behavior.

Answer

You can use RecyclerView.ItemDecoration to implement this behavior.

public class StickyFooterItemDecoration extends RecyclerView.ItemDecoration {

    /**
     * Top offset to completely hide footer from the screen and therefore avoid noticeable blink during changing position of the footer.
     */
    private static final int OFF_SCREEN_OFFSET = 5000;

    @Override
    public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) {
        int adapterItemCount = parent.getAdapter().getItemCount();
        if (isFooter(parent, view, adapterItemCount)) {
            //For the first time, each view doesn't contain any parameters related to its size,
            //hence we can't calculate the appropriate offset.
            //In this case, set a big top offset and notify adapter to update footer one more time.
            //Also, we shouldn't do it if footer became visible after scrolling.
            if (view.getHeight() == 0 && state.didStructureChange()) {
                hideFooterAndUpdate(outRect, view, parent);
            } else {
                outRect.set(0, calculateTopOffset(parent, view, adapterItemCount), 0, 0);
            }
        }
    }

    private void hideFooterAndUpdate(Rect outRect, final View footerView, final RecyclerView parent) {
        outRect.set(0, OFF_SCREEN_OFFSET, 0, 0);
        footerView.post(new Runnable() {
            @Override
            public void run() {
                parent.getAdapter().notifyDataSetChanged();
            }
        });
    }

    private int calculateTopOffset(RecyclerView parent, View footerView, int itemCount) {
        int topOffset = parent.getHeight() - visibleChildsHeightWithFooter(parent, footerView, itemCount);
        return topOffset < 0 ? 0 : topOffset;
    }

    private int visibleChildsHeightWithFooter(RecyclerView parent, View footerView, int itemCount) {
        int totalHeight = 0;
        //In the case of dynamic content when adding or removing are possible itemCount from the adapter is reliable,
        //but when the screen can fit fewer items than in adapter, getChildCount() from RecyclerView should be used.
        int onScreenItemCount = Math.min(parent.getChildCount(), itemCount);
        for (int i = 0; i < onScreenItemCount - 1; i++) {
            totalHeight += parent.getChildAt(i).getHeight();
        }
        return totalHeight + footerView.getHeight();
    }

    private boolean isFooter(RecyclerView parent, View view, int itemCount) {
        return parent.getChildAdapterPosition(view) == itemCount - 1;
    }
}

Make sure to set match_parent for the RecyclerView height.

Please have a look at the sample application https://github.com/JohnKuper/recyclerview-sticky-footer and how it works http://sendvid.com/nbpj0806

A Huge drawback of this solution is it works correctly only after notifyDataSetChanged() throughout an application(not inside decoration). With more specific notifications it won’t work properly and to support them, it requires a way more logic. Also, you can get insights from the library recyclerview-stickyheaders by eowise and improve this solution.

We are here to answer your question about How implement sticky footer in recyclerview - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji