How to add dividers and spaces between items in RecyclerView?

前端 未结 30 2857
清歌不尽
清歌不尽 2020-11-22 03:27

This is an example of how it could have been done previously in the ListView class, using the divider and dividerHeight parame

30条回答
  •  醉酒成梦
    2020-11-22 04:07

    I forked the DividerItemDecoration from an older gist and simplified it to fit my use case, and I also modified it to draw the dividers the way they are drawn in ListView, including a divider after the last list item. This will also handle vertical ItemAnimator animations:

    1) Add this class to your project:

    public class DividerItemDecoration extends RecyclerView.ItemDecoration {
        private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
        private Drawable divider;
    
        public DividerItemDecoration(Context context) {
            try {
                final TypedArray a = context.obtainStyledAttributes(ATTRS);
                divider = a.getDrawable(0);
                a.recycle();
            } catch (Resources.NotFoundException e) {
                // TODO Log or handle as necessary.
            }
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            if (divider == null) return;
            if (parent.getChildAdapterPosition(view) < 1) return;
    
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
                outRect.top = divider.getIntrinsicHeight();
            else
                throw new IllegalArgumentException("Only usable with vertical lists");
        }
    
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            if (divider == null) {
                super.onDrawOver(c, parent, state);
                return;
            }
    
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();
            final int childCount = parent.getChildCount();
    
            for (int i = 0; i < childCount; ++i) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                final int size = divider.getIntrinsicHeight();
                final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
                final int bottom = top + size;
                divider.setBounds(left, top, right, bottom);
                divider.draw(c);
    
                if (i == childCount - 1) {
                    final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
                    final int newBottom = newTop + size;
                    divider.setBounds(left, newTop, right, newBottom);
                    divider.draw(c);
                }
            }
        }
    
        private int getOrientation(RecyclerView parent) {
            if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
                throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
            return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        }
    }
    

    2) Add the decorator to your RecylerView:

    recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
    

提交回复
热议问题