How to add dividers and spaces between items in RecyclerView?

前端 未结 30 2810
清歌不尽
清歌不尽 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()));
    
    0 讨论(0)
  • 2020-11-22 04:08

    1.One of the Way is by using cardview and recycler view together we can easily add effect like divider. ex.https://developer.android.com/training/material/lists-cards.html

    2.and other is by adding view as divider to list_item_layout of recycler view.

            <View
                android:id="@+id/view1"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/colorAccent" />
    
    0 讨论(0)
  • 2020-11-22 04:09
    • Here is simple hack to add divider
    • Just add a background to the layout of your recycler item as follows

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@drawable/shape_border"
          android:gravity="center"
          android:orientation="horizontal"
          android:padding="5dp">
      
      <ImageView
          android:id="@+id/imageViewContactLogo"
          android:layout_width="60dp"
          android:layout_height="60dp"
          android:layout_marginRight="10dp"
          android:src="@drawable/ic_user" />
      
      <LinearLayout
          android:id="@+id/linearLayout"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_weight="0.92"
          android:gravity="center|start"
          android:orientation="vertical">
      
      <TextView
          android:id="@+id/textViewContactName"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:singleLine="true"
          android:text="Large Text"
          android:textAppearance="?android:attr/textAppearanceLarge" />
      
      <TextView
          android:id="@+id/textViewStatusOrNumber"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginTop="5dp"
          android:singleLine="true"
          android:text=""
          android:textAppearance="?android:attr/textAppearanceMedium" />
      </LinearLayout>
      
      <TextView
          android:id="@+id/textViewUnreadCount"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginRight="10dp"
          android:padding="5dp"
          android:text=""
          android:textAppearance="?android:attr/textAppearanceMedium"
          android:textColor="@color/red"
          android:textSize="22sp" />
      
      <Button
          android:id="@+id/buttonInvite"
          android:layout_width="54dp"
          android:layout_height="wrap_content"
          android:background="@drawable/ic_add_friend" />
      </LinearLayout>
      

    Create following shape_border.xml in drawable folder

      <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
          android:shape="rectangle" >
           <gradient
            android:angle="270"
            android:centerColor="@android:color/transparent"
            android:centerX="0.01"
            android:startColor="#000" />
        </shape>
    

    Here is final result - a RecyclerView with divider.

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

    You can add with programaticly easily.

    If your Layout Manager is Linearlayout then you can use:

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

     mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
             mLayoutManager.getOrientation());
     recyclerView.addItemDecoration(mDividerItemDecoration);
    

    source

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

    Simple ItemDecoration implementation for equal spaces between all items.

    public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
        private int space;
    
        public SpacesItemDecoration(int space) {
            this.space = space;
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.left = space;
            outRect.right = space;
            outRect.bottom = space;
    
            // Add top margin only for the first item to avoid double space between items
            if(parent.getChildAdapterPosition(view) == 0) {
                outRect.top = space;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:11

    I think using simple divider will help you

    To add divider to each item:
    1- Add this to drawable directory line_divider.xml

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

    2- Create SimpleDividerItemDecoration class
    I used this example to define this class:
    https://gist.github.com/polbins/e37206fbc444207c0e92

    package com.example.myapp;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Canvas;
    import android.graphics.drawable.Drawable;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import com.example.myapp.R;
    
    public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration{
    private Drawable mDivider;
    
    public SimpleDividerItemDecoration(Resources resources) {
        mDivider = resources.getDrawable(R.drawable.line_divider);
    }
    
    public void onDrawOver(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 + mDivider.getIntrinsicHeight();
    
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
      }
    }
    


    3- In activity or fragment that using RecyclerView, inside onCreateView add this:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
     RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
     myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
     ....
     }
    


    4- To add spacing between Items
    you just need to add padding property to your item view

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="4dp"
    >
    ..... item structure
    </RelativeLayout>
    
    0 讨论(0)
提交回复
热议问题