How to add dividers and spaces between items in RecyclerView?

前端 未结 30 2853
清歌不尽
清歌不尽 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:16
    public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {
    
            private int mSpace = 0;
            private boolean mVerticalOrientation = true;
    
        public CommonItemSpaceDecoration(int space) {
            this.mSpace = space;
        }
    
        public CommonItemSpaceDecoration(int space, boolean verticalOrientation) {
            this.mSpace = space;
            this.mVerticalOrientation = verticalOrientation;
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.top = SizeUtils.dp2px(view.getContext(), mSpace);
            if (mVerticalOrientation) {
                if (parent.getChildAdapterPosition(view) == 0) {
                    outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace));
                } else {
                    outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace));
                }
            } else {
                if (parent.getChildAdapterPosition(view) == 0) {
                    outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0);
                } else {
                    outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0);
                }
            }
        }
    }
    

    This will add space in every item's top and bottom(or left and right).Then you can set it to your recyclerView.

    recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));
    

    SizeUtils.java

    public class SizeUtils {
        public static int dp2px(Context context, float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:18

    Might I direct your attention to this particular file on Github by Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

    It's the DividerItemDecoration.java example file "pulled straight from the support demos".(https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS)

    I was able to get divider lines nicely after importing this file in my project and add it as an item decoration to the recycler view.

    Here's how my onCreateView look like in my fragment containing the Recyclerview:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
    
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
    
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    
        return rootView;
    }
    

    I'm sure additional styling can be done, but it's a starting point. :)

    0 讨论(0)
  • 2020-11-22 04:18

    As I have set ItemAnimators. The ItemDecorator don't enter or exit along with the animation.

    I simply ended up in having a view line in my item view layout file of each item. It solved my case. DividerItemDecoration felt to be too much of sorcery for a simple divider.

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="@color/lt_gray"/>
    
    0 讨论(0)
  • 2020-11-22 04:23

    The simple one is to set background color for RecyclerView and different background color for items. Here is an example ...

    <android.support.v7.widget.RecyclerView
        android:background="#ECEFF1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"/>
    

    and the TextView item (It can be anything though) with bottom margin "x" dp or px.

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="1dp"
        android:background="#FFFFFF"/>
    

    The output ...

    enter image description here

    0 讨论(0)
  • 2020-11-22 04:23

    This doesn't actually solve the problem, but as a temporary workaround, you can set the useCompatPadding property on the card in your XML layout to make it measure the same as it does on pre-Lollipop versions.

    card_view:cardUseCompatPadding="true"
    
    0 讨论(0)
  • 2020-11-22 04:24

    October 2016 Update

    The version 25.0.0 of Android Support Library introduced DividerItemDecoration class:

    DividerItemDecoration is a RecyclerView.ItemDecoration that can be used as a divider between items of a LinearLayoutManager. It supports both HORIZONTAL and VERTICAL orientations.

    Usage:

    DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
        layoutManager.getOrientation());
    recyclerView.addItemDecoration(dividerItemDecoration);
    

    Previous answer

    Some answers either use methods that have since become deprecated, or don't give a complete solution, so I tried to do a short, up-to-date wrap-up.


    Unlike ListView, the RecyclerView class has no divider-related parameters. Instead, you need to extend ItemDecoration, a RecyclerView's inner class:

    An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter's data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.

    All ItemDecorations are drawn in the order they were added, before the item views (in onDraw()) and after the items (in onDrawOver(Canvas, RecyclerView, RecyclerView.State).

    Vertical spacing ItemDecoration

    Extend ItemDecoration, add custom constructor which takes space height as a parameter and override getItemOffsets() method:

    public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
    
        private final int verticalSpaceHeight;
    
        public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
            this.verticalSpaceHeight = verticalSpaceHeight;
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                RecyclerView.State state) {
            outRect.bottom = verticalSpaceHeight;
        }
    }
    

    If you don't want to insert space below the last item, add the following condition:

    if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
                outRect.bottom = verticalSpaceHeight;
    }
    

    Note: you can also modify outRect.top, outRect.left and outRect.right properties for desired effect.

    Divider ItemDecoration

    Extend ItemDecoration and override onDraw() method:

    public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    
        private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    
        private Drawable divider;
    
        /**
         * Default divider will be used
         */
        public DividerItemDecoration(Context context) {
            final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
            divider = styledAttributes.getDrawable(0);
            styledAttributes.recycle();
        }
    
        /**
         * Custom divider will be used
         */
        public DividerItemDecoration(Context context, int resId) {
            divider = ContextCompat.getDrawable(context, resId);
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
    
            int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = parent.getChildAt(i);
    
                RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
    
                int top = child.getBottom() + params.bottomMargin;
                int bottom = top + divider.getIntrinsicHeight();
    
                divider.setBounds(left, top, right, bottom);
                divider.draw(c);
            }
        }
    }
    

    You can either call the first constructor that uses the default Android divider attributes, or the second one that uses your own drawable, for example drawable/divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle">
        <size android:height="1dp" />
        <solid android:color="#ff992900" />
    </shape>
    

    Note: if you want the divider to be drawn over your items, override onDrawOver() method instead.

    Usage

    To use your new class add VerticalSpaceItemDecoration or DividerSpaceItemDecoration to RecyclerView, for example in your fragment's onCreateView() method:

    private static final int VERTICAL_ITEM_SPACE = 48;
    private RecyclerView recyclerView;
    private LinearLayoutManager linearLayoutManager;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
    
        recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view);
        linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        
        //add ItemDecoration
        recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));
        //or
        recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
        //or
        recyclerView.addItemDecoration(
                new DividerItemDecoration(getActivity(), R.drawable.divider));
    
        recyclerView.setAdapter(...);
    
        return rootView;
    }
    

    There's also Lucas Rocha's library which is supposed to simplify the item decoration process. Haven't tried it though.

    Among its features are:

    • A collection of stock item decorations including:
    • Item spacing Horizontal/vertical dividers.
    • List item
    0 讨论(0)
提交回复
热议问题