Decorating RecyclerView (with GridLayoutManager) to display divider between items

后端 未结 9 1451
旧时难觅i
旧时难觅i 2020-12-07 09:44

What\'s the best and easiest way to decorate RecyclerView to have such look & feel?

\"enter

9条回答
  •  既然无缘
    2020-12-07 10:05

    Here's a simpler and more user-friendly implementation:

    public class MediaSpaceDecoration extends RecyclerView.ItemDecoration {
        private final int spacing;
        private final List allowedViewTypes = Arrays.asList(
                R.layout.item_image,
                R.layout.item_blur);
    
        public MediaSpaceDecoration(int spacing) {
            this.spacing = spacing;
        }
    
        @Override
        public void getItemOffsets(Rect outRect,
                                   View view,
                                   RecyclerView parent,
                                   RecyclerView.State state) {
            final int position = parent.getChildAdapterPosition(view);
            if (!isMedia(parent, position)) {
                return;
            }
    
            final int totalSpanCount = getTotalSpanCount(parent);
            int spanSize = getItemSpanSize(parent, position);
            if (totalSpanCount == spanSize) {
                return;
            }
    
            outRect.top = isInTheFirstRow(position, totalSpanCount) ? 0 : spacing;
            outRect.left = isFirstInRow(position, totalSpanCount) ? 0 : spacing / 2;
            outRect.right = isLastInRow(position, totalSpanCount) ? 0 : spacing / 2;
            outRect.bottom = 0; // don't need
        }
    
        private boolean isInTheFirstRow(int position, int spanCount) {
            return position < spanCount;
        }
    
        private boolean isFirstInRow(int position, int spanCount) {
            return position % spanCount == 0;
        }
    
        private boolean isLastInRow(int position, int spanCount) {
            return isFirstInRow(position + 1, spanCount);
        }
    
        private int getTotalSpanCount(RecyclerView parent) {
            final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
            return layoutManager instanceof GridLayoutManager
                ? ((GridLayoutManager) layoutManager).getSpanCount()
                : 1;
        }
    
        private int getItemSpanSize(RecyclerView parent, int position) {
            final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
            return layoutManager instanceof GridLayoutManager
                ? ((GridLayoutManager) layoutManager).getSpanSizeLookup().getSpanSize(position)
                : 1;
        }
    
        private boolean isMedia(RecyclerView parent, int viewPosition) {
            final RecyclerView.Adapter adapter = parent.getAdapter();
            final int viewType = adapter.getItemViewType(viewPosition);
            return allowedViewTypes.contains(viewType);
        }
    }
    

    I also check before setting the outRect because I have various spanSizes for each viewType and I need to add an extra middle-space only for allowedViewTypes. You can easily remove that verification and the code would be even simpler. It looks like this for me:

提交回复
热议问题