Android: Add divider between items in RecyclerView

2019-02-06 05:44发布

I am using RecyclerView with rounded corner, to make it rounded corner I used below XML:

view_rounded.xml:-

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#008f8471"/>
    <stroke android:width="2dp" android:color="#ffffff" />
    <corners android:radius="10dp"/>
</shape>

fragment_main.xml:-

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/view_rounded"/>

adapter_main.xml:-

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textTitle"
        style="@style/AppTheme.ListTextView"
        />

</LinearLayout>

style.xml:-

<style name="AppTheme.ListTextView" parent="android:Widget.Material.TextView">
  <item name="android:gravity">left</item>
  <item name="android:layout_width">match_parent</item>
  <item name="android:layout_height">wrap_content</item>
  <item name="android:textAllCaps">false</item>
  <item name="android:padding">10dp</item>
  <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
  <item name="android:textColor">@color/tabsScrollColor</item> 
  <item name="android:textStyle">bold</item> 
</style>

Getting (without item separator):

enter image description here

Required (with item separator):

enter image description here

16条回答
放荡不羁爱自由
2楼-- · 2019-02-06 06:21

Try This From Reference Android: ListView with rounded corners

First off, we need the drawables for the backgrounds of the Lists entries: For the entries in the middle of the list, we don't need rounded corners, so create a xml in your drawable folder "list_entry_middle.xml" with following content:

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item>
  <shape>
        <stroke android:width="1px" android:color="#ffbbbbbb" />
  </shape>
</item>
<item android:bottom="1dp" android:left="1dp" android:right="1dp">
 <shape >
       <solid android:color="#ffffffff" />
 </shape>
</item>
</layer-list>

For the rounded corners, create another xml, "rounded_corner_top.xml":

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item>
  <shape>
        <stroke android:width="1dp" android:color="#ffbbbbbb" />
        <corners android:topLeftRadius="20dp"
    android:topRightRadius="20dp"
     />
  </shape>
</item>
<item android:top="1dp" android:left="1dp" android:right="1dp" android:bottom="1dp">
 <shape >
       <solid android:color="#ffffffff" />
      <corners android:topLeftRadius="20dp"
    android:topRightRadius="20dp"
     />
 </shape>
 </item>

 </layer-list>

Implementing the bottom part is quite the same, just with bottomLeftRadius and bottomRightRadius. (maybe also create one with all corners rounded, if the list only has one entry) For better usability, also provide drawables with other colors for the different states, that the list item can have and reference them in another xml in the drawable folder ("selector_rounded_corner_top.xml") as followed:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/rounded_corner_top_click"
      android:state_pressed="true" />
    <item android:drawable="@drawable/rounded_corner_top_click"
      android:state_focused="true" />
    <item android:drawable="@drawable/rounded_corner_top" />
</selector>

Now do the same for the other backgrounds of the list. All that is left now, is to assign the right backgrounds in our ListAdapter like following:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //...      
    //skipping the view reuse stuff

   if (position == 0 && entry_list.size() == 1) {
            view.setBackgroundResource(R.drawable.selector_rounded_corner);
        } else if (position == 0) {
            view.setBackgroundResource(R.drawable.selector_rounded_corner_top);
        } else if (position == entry_list.size() - 1) {
            view.setBackgroundResource(R.drawable.selector_rounded_corner_bottom);
        } else {
            view.setBackgroundResource(R.drawable.selector_middle);
        }

       //...
       //skipping the filling of the view
   }
查看更多
闹够了就滚
3楼-- · 2019-02-06 06:26

To add dividers to your recyclerview you need to use decorator - https://gist.github.com/alexfu/0f464fc3742f134ccd1e after you add that to your project add a line recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

查看更多
叼着烟拽天下
4楼-- · 2019-02-06 06:27

Use this drawable xml for curve shape listview and set background to your list view or any layout:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
           <corners android:radius="6dp" />

            <padding android:bottom="3dp" android:left="3dp" android:right="3dp" android:top="3dp" />
        </shape>
查看更多
SAY GOODBYE
5楼-- · 2019-02-06 06:29

The problem is because you are setting the background with corners not only to the list view, but also to the item. You should make separate backgrounds for item (with selector) and one for list view with corners.

list_bg.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#008f8471"/>
    <stroke android:width="1dip" android:color="#ffffff" />
    <corners android:radius="10dp"/>
    <padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

Now you can setup this drawable as the background of your list view.

<ListView
    android:id="@+id/listView"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/list_bg.xml"
    android:fastScrollEnabled="true"
    android:choiceMode="singleChoice" />

And for list view item you can use selector to have hover functionality: list_item_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/list_item_selected" android:state_pressed="true"/>
    <item android:drawable="@drawable/list_item_selected" android:state_pressed="false" android:state_selected="true"/>
    <item android:drawable="@android:color/transparent"/>

Where list_item_selected is : list_item_selected.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#4d8f8471"/>
    <stroke android:width="1dip" android:color="#ffffff" />
</shape>

And after that you can setup this selector to the item in your xml:

<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"        
    android:background="@drawable/list_item_selector" />

So your list view will have always same background with corners, and the background of items of list view, will be without corners and will be changed in pressed or selected state.

查看更多
虎瘦雄心在
6楼-- · 2019-02-06 06:31

you are setting list_selector for both textview and listview background. Use list_selector only for listview and if you want hover effect on textview too, then create another list_selector_textview which haven't include the <corners android:radius="10dp" property.

查看更多
Melony?
7楼-- · 2019-02-06 06:35

RecyclerView doesn’t have any divider related parameters to display the divider. Instead you need to extend a class from ItemDecoration and use addItemDecoration() method to display the divider.

Create a class named DividerItemDecoration.java and paste the below code.

DividerItemDecoration.java

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Drawable mDivider;

    private int mOrientation;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        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 top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        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 left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

Open Activity.java and set the item decoration using addItemDecoration() method before setting the adapter.

recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));

// set the adapter
recyclerView.setAdapter(mAdapter);
查看更多
登录 后发表回答