Listview - Footer at the bottom of screen

前端 未结 4 527

I have a ListView with a footer added with listview.addFooterView(footerView);

All works as expected excepted in one case: when my listview\'s items doe

4条回答
  •  南方客
    南方客 (楼主)
    2020-12-17 16:48

    After spent a lot of time to research, I found the best solution for it. Please have a look at: https://stackoverflow.com/a/38890559/6166660 and https://github.com/JohnKuper/recyclerview-sticky-footer

    For details:

    • Create a StickyFooterItemDecoration extends RecyclerView.ItemDecoration like the example code below.
    • After that, set ItemDecoration to your recyclerView:

    recyclerListView.addItemDecoration(new StickyFooterItemDecoration());

    ---------------------------------------

     public class StickyFooterItemDecoration extends RecyclerView.ItemDecoration {
    
        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)) {
                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;
            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;
        }
    }
    

提交回复
热议问题