it-swarm.com.de

Wie füge ich Trennlinien und Leerzeichen zwischen Elementen in RecyclerView hinzu?

Dies ist ein Beispiel dafür, wie dies zuvor in der Klasse ListView mit den Parametern divider und dividerHeight hätte geschehen können:

<ListView
    Android:id="@+id/activity_home_list_view"
    Android:layout_width="match_parent" 
    Android:layout_height="match_parent"
    Android:divider="@Android:color/transparent"
    Android:dividerHeight="8dp"/>

Ich sehe diese Möglichkeit jedoch nicht in der Klasse RecyclerView.

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/activity_home_recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:scrollbars="vertical"/>

Ist es in diesem Fall in Ordnung, Ränder zu definieren und/oder eine benutzerdefinierte Teileransicht direkt in das Layout eines Listenelements einzufügen, oder gibt es einen besseren Weg, um mein Ziel zu erreichen?

848
EyesClear

Oktober 2016 Update

Die Version 25.0.0 von Android Support Library wurde eingeführt DividerItemDecoration class:

DividerItemDecoration ist eine RecyclerView.ItemDecoration, die als Trennlinie zwischen Elementen eines LinearLayoutManager verwendet werden kann. Es unterstützt sowohl HORIZONTAL- als auch VERTICAL-Ausrichtungen.

Verwendungszweck:

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

Vorherige Antwort

Einige Antworten verwenden entweder Methoden, die inzwischen veraltet sind, oder geben keine vollständige Lösung an. Deshalb habe ich versucht, eine kurze, aktuelle Zusammenfassung zu erstellen.


Im Gegensatz zu ListView hat die Klasse RecyclerView keine teilerbezogenen Parameter. Stattdessen müssen Sie ItemDecoration , die innere Klasse von RecyclerView, erweitern:

Mit ItemDecoration kann die Anwendung bestimmten Elementansichten aus dem Datensatz des Adapters einen speziellen Zeichnungs- und Layoutversatz hinzufügen. Dies kann nützlich sein, um Trennlinien zwischen Elementen, Hervorhebungen, visuellen Gruppierungsgrenzen usw. zu zeichnen.

Alle ItemDecorations werden in der Reihenfolge gezeichnet, in der sie hinzugefügt wurden, vor den Elementansichten (in onDraw()) und nach den Elementen (in onDrawOver (Canvas, RecyclerView, RecyclerView.State)).

Vertical Abstand ItemDecoration

Erweitern Sie ItemDecoration, fügen Sie einen benutzerdefinierten Konstruktor hinzu, der height als Parameter verwendet, und überschreiben Sie die getItemOffsets() -Methode:

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;
    }
}

Wenn Sie unter dem letzten Element kein Leerzeichen einfügen möchten, fügen Sie die folgende Bedingung hinzu:

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

Hinweis: Sie können auch die Eigenschaften outRect.top, outRect.left und outRect.right für den gewünschten Effekt ändern.

Teiler ItemDecoration

ItemDecoration erweitern und onDraw()-Methode überschreiben:

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);
        }
    }
}

Sie können entweder den ersten Konstruktor aufrufen, der die standardmäßigen Android Teilerattribute verwendet, oder den zweiten, der Ihre eigene Zeichendatei verwendet, z. B. 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>

Hinweis: Wenn Sie möchten, dass der Teiler über Ihre Elemente gezogen wird , überschreiben Sie stattdessen die onDrawOver() -Methode.

Verwendungszweck

Um Ihre neue Klasse zu verwenden, fügen Sie VerticalSpaceItemDecoration oder DividerSpaceItemDecoration zu RecyclerView hinzu, zum Beispiel in der onCreateView() -Methode Ihres Fragments:

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;
}

Es gibt auch Lucas Rochas Bibliothek , das den Prozess der Dekoration von Gegenständen vereinfachen soll. Hab es aber nicht ausprobiert.

Zu seinen Features gehören:

  • Eine Sammlung von Lagerartikel-Dekorationen, darunter:
  • Artikelabstand Horizontale/vertikale Teiler.
  • Listenpunkt
1109
EyesClear

Einfach hinzufügen

recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
                DividerItemDecoration.VERTICAL));

Möglicherweise müssen Sie auch die Abhängigkeit hinzufügen
compile 'com.Android.support:recyclerview-v7:27.1.0'

EDIT:

Um es ein wenig anzupassen, können Sie ein benutzerdefiniertes Zeichenelement hinzufügen:

DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.divider));

Sie können beliebige benutzerdefinierte Zeichen verwenden, zum Beispiel:

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
       Android:shape="rectangle">
    <solid Android:color="@color/colorPrimary"/>
    <size Android:height="0.5dp"/>
</shape>
425
Leo Droidcoder

Könnte ich Ihre Aufmerksamkeit auf diese bestimmte Datei auf Github von Alex Fu lenken: https://Gist.github.com/alexfu/0f464fc3742f134ccd1e

Dies ist die DividerItemDecoration.Java-Beispieldatei, die direkt aus den Support-Demos abgerufen wurde. ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

Nachdem ich diese Datei in mein Projekt importiert habe, konnte ich Trennlinien erhalten und sie als Objektdekoration zur Ansicht des Recyclers hinzufügen.

So sieht mein onCreateView in meinem Fragment mit der Recyclerview aus:

@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;
}

Ich bin sicher, dass zusätzliches Styling möglich ist, aber es ist ein Ausgangspunkt. :)

251
Duy Nguyen

Einfache ItemDecoration Implementierung für gleiche Abstände zwischen allen Elementen.

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;
        }
    }
}
150
SergeyA

Die einfache Methode besteht darin, die Hintergrundfarbe für RecyclerView und andere Hintergrundfarben für Elemente festzulegen. Hier ist ein Beispiel ...

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

und das TextView Element (es kann aber alles sein) mit dem unteren Rand "x" dp oder px.

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

Die Ausgabe ...

enter image description here

104
Madan Sapkota

Ich denke, die Verwendung eines einfachen Teilers wird Ihnen helfen

So fügen Sie jedem Element einen Teiler hinzu:
1- Fügen Sie dies zu einem zeichnungsfähigen Verzeichnis hinzu 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- Erstellen Sie die SimpleDividerItemDecoration-Klasse
Ich habe dieses Beispiel verwendet, um diese Klasse zu definieren:
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- Fügen Sie bei Aktivitäten oder Fragmenten, die RecyclerView verwenden, in onCreateView Folgendes hinzu:

@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- Abstand zwischen Elementen hinzufügen
Sie müssen Ihrer Artikelansicht lediglich eine Auffülleigenschaft hinzufügen

<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>
41
Belal mazlom

Da habe ich ItemAnimators eingestellt. Das ItemDecorator tritt nicht zusammen mit der Animation ein oder aus.

Am Ende hatte ich einfach eine Ansichtszeile in der Layoutdatei für die Artikelansicht jedes Artikels. Es hat meinen Fall gelöst. DividerItemDecoration empfand einen einfachen Teiler als zu zaubernd.

<View
    Android:layout_width="match_parent"
    Android:layout_height="1px"
    Android:layout_marginLeft="5dp"
    Android:layout_marginRight="5dp"
    Android:background="@color/lt_gray"/>
31
Javanator

Das ist einfach, Sie brauchen keinen so komplizierten Code

DividerItemDecoration divider = new 
DividerItemDecoration(mRVMovieReview.getContext(), 
DividerItemDecoration.VERTICAL);
divider.setDrawable(
    ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)
);
mRVMovieReview.addItemDecoration(divider);

Fügen Sie dies in Ihre Drawable ein: 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:height="1dp" />
    <solid Android:color="@Android:color/black" />
</shape>
21
Faheem

Da es keinen richtigen Weg gibt, dies mithilfe von Material Design zu implementieren, habe ich einfach den folgenden Trick ausgeführt, um einen Teiler direkt zum Listenelement hinzuzufügen:

<View
Android:layout_width="match_parent"
Android:layout_height="1dp"
Android:background="@color/dividerColor"/>
21
Yoann Hercouet

UPDATE OKTOBER 2016

Mit der Unterstützungsbibliothek v25.0.0 ist endlich eine Standardimplementierung grundlegender horizontaler und vertikaler Teiler verfügbar!

https://developer.Android.com/reference/Android/support/v7/widget/DividerItemDecoration.html

15
friday

Wenn jemand beispielsweise nur einen Abstand von 10 dpi zwischen Elementen hinzufügen möchte, können Sie dies tun, indem Sie eine Zeichenfunktion auf DividerItemDecoration setzen:

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

dividerItemDecoration.setDrawable(
    ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp)
); 

Wobei divider_10dp eine ziehbare Ressource ist, die Folgendes enthält:

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle">
    <size Android:height="10dp"/>
    <solid Android:color="@Android:color/transparent"/>
</shape>
14
Praveen Singh

Für diejenigen, die nur nach Leerzeichen zwischen den Elementen im RecyclerView suchen, siehe meine Vorgehensweise, bei der Sie gleiche Leerzeichen zwischen allen Elementen erhalten, außer bei den ersten und letzten Elementen, bei denen ich einen größeren Abstand angegeben habe. Ich fülle nur horizontal LayoutManager nach links/rechts und vertikal LayoutManager nach oben/unten auf.

public class PaddingItemDecoration extends RecyclerView.ItemDecoration {

    private int mPaddingPx;
    private int mPaddingEdgesPx;

    public PaddingItemDecoration(Activity activity) {
        final Resources resources = activity.getResources();
        mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault);
        mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        final int itemPosition = parent.getChildAdapterPosition(view);
        if (itemPosition == RecyclerView.NO_POSITION) {
            return;
        }
        int orientation = getOrientation(parent);
        final int itemCount = state.getItemCount();

        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;

        /** HORIZONTAL */
        if (orientation == LinearLayoutManager.HORIZONTAL) {
            /** all positions */
            left = mPaddingPx;
            right = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                left += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                right += mPaddingEdgesPx;
            }
        }
        /** VERTICAL */
        else {
            /** all positions */
            top = mPaddingPx;
            bottom = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                top += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                bottom += mPaddingEdgesPx;
            }
        }

        if (!isReverseLayout(parent)) {
            outRect.set(left, top, right, bottom);
        } else {
            outRect.set(right, bottom, left, top);
        }
    }

    private boolean isReverseLayout(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getReverseLayout();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

dimens.xml

<resources>
    <dimen name="paddingItemDecorationDefault">10dp</dimen>
    <dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
11
Ryan Amaral
  • Hier ist ein einfacher Hack, um einen Teiler hinzuzufügen
  • Fügen Sie dem Layout Ihres Recyclingartikels einfach wie folgt einen Hintergrund hinzu

    <?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>
    

Erstellen Sie die folgende Datei shape_border.xml in einem zeichnungsfähigen Ordner

  <?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>

Hier ist das Endergebnis - ein RecyclerView mit Teiler.

Here is final result - a RecyclerView with divider.

11
turbandroid

Dies löst das Problem nicht wirklich, aber als vorübergehende Problemumgehung können Sie die seCompatPadding -Eigenschaft für die Karte in Ihrem XML-Layout festlegen, damit sie die gleiche Größe hat wie bei Versionen vor Lollipop.

card_view:cardUseCompatPadding="true"
10
Kevin Grant

Fügen Sie Ihrer Ansicht einen Rand hinzu, es hat bei mir funktioniert.

Android:layout_marginTop="10dp"

Wenn Sie nur gleicher Abstand hinzufügen möchten und dies in XML tun möchten, setzen Sie padding auf RecyclerView und den gleichen Betrag von layoutMargin zu dem Element, das Sie in Ihr RecyclerView aufblasen, und lassen Sie die Hintergrundfarbe die Abstandsfarbe bestimmen.

10
Quantum Mattter

Ich habe die DividerItemDecoration von einem älteren Gist abgeleitet und sie für meinen Anwendungsfall vereinfacht. Außerdem habe ich sie so geändert, dass die Teiler so gezeichnet werden, wie sie in ListView gezeichnet werden, einschließlich eines Teilers nach dem letzten Listenelement. Hiermit werden auch vertikale ItemAnimator-Animationen verarbeitet:

1) Fügen Sie diese Klasse Ihrem Projekt hinzu:

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) Fügen Sie den Dekorateur zu Ihrem RecylerView hinzu:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
9
Learn OpenGL ES

Wir können die Gegenstände mit verschiedenen Dekoratoren dekorieren, die der Recycling-Übersicht beigefügt sind, wie zum Beispiel DividerItemDecoration:

Verwenden Sie einfach Folgendes ... aus der Antwort von EyesClear

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

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

private Drawable mDivider;

/**
 * Default divider will be used
 */
public DividerItemDecoration(Context context) {
    final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
    mDivider = styledAttributes.getDrawable(0);
    styledAttributes.recycle();
}

/**
 * Custom divider will be used
 */
public DividerItemDecoration(Context context, int resId) {
    mDivider = 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 + mDivider.getIntrinsicHeight();

        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

} und dann wie folgt vorgehen

RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(itemDecoration);

Dadurch werden Trennlinien zwischen den einzelnen Elementen in der Liste angezeigt, wie unten gezeigt:

enter image description here

Und für diejenigen, die nach mehr Details suchen, können Sie diese Anleitung lesen Verwenden von RecyclerView _ CodePath Android Cliffnotes

Einige Antworten hier schlagen die Verwendung von Rändern vor, aber der Haken ist: Wenn Sie sowohl obere als auch untere Ränder hinzufügen, werden beide zwischen Elementen hinzugefügt und sie sind zu groß. Wenn Sie nur einen der beiden Werte hinzufügen, wird am oberen oder unteren Rand der gesamten Liste kein Rand angezeigt. Wenn Sie die Hälfte des Abstands oben und die Hälfte unten hinzufügen, sind die äußeren Ränder zu klein.

Daher ist die einzige ästhetisch korrekte Lösung die Teilung, bei der das System weiß, wo es richtig anzuwenden ist: zwischen Elementen, jedoch nicht über oder unter Elementen.

Bitte teilen Sie mir Ihre Zweifel in den Kommentaren unten mit :)

6
Anudeep Samaiya

Dieser Link hat für mich wie ein Zauber gewirkt:

https://Gist.github.com/lapastillaroja/858caf1a82791b6c1a36

import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Canvas;
import Android.graphics.Rect;
import Android.graphics.drawable.Drawable;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.util.AttributeSet;
import Android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;
    private boolean mShowFirstDivider = false;
    private boolean mShowLastDivider = false;


    public DividerItemDecoration(Context context, AttributeSet attrs) {
        final TypedArray a = context
                .obtainStyledAttributes(attrs, new int[]{Android.R.attr.listDivider});
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
            boolean showLastDivider) {
        this(context, attrs);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    public DividerItemDecoration(Drawable divider) {
        mDivider = divider;
    }

    public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
            boolean showLastDivider) {
        this(divider);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
            RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (mDivider == null) {
            return;
        }
        if (parent.getChildPosition(view) < 1) {
            return;
        }

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
            outRect.top = mDivider.getIntrinsicHeight();
        } else {
            outRect.left = mDivider.getIntrinsicWidth();
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mDivider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        // Initialization needed to avoid compiler warning
        int left = 0, right = 0, top = 0, bottom = 0, size;
        int orientation = getOrientation(parent);
        int childCount = parent.getChildCount();

        if (orientation == LinearLayoutManager.VERTICAL) {
            size = mDivider.getIntrinsicHeight();
            left = parent.getPaddingLeft();
            right = parent.getWidth() - parent.getPaddingRight();
        } else { //horizontal
            size = mDivider.getIntrinsicWidth();
            top = parent.getPaddingTop();
            bottom = parent.getHeight() - parent.getPaddingBottom();
        }

        for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getTop() - params.topMargin;
                bottom = top + size;
            } else { //horizontal
                left = child.getLeft() - params.leftMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

        // show last divider
        if (mShowLastDivider && childCount > 0) {
            View child = parent.getChildAt(childCount - 1);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getBottom() + params.bottomMargin;
                bottom = top + size;
            } else { // horizontal
                left = child.getRight() + params.rightMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException(
                    "DividerItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

Dann in Ihrer Tätigkeit:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(this, null));

Oder dies, wenn Sie ein Fragment verwenden:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(getActivity(), null));
6
Micro

Aus einer Google-Suche entnommen, fügen Sie dieses ItemDecoration zu Ihrem RecyclerView hinzu:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;


public DividerItemDecoration(Context context, AttributeSet attrs) {
    final TypedArray a = context
            .obtainStyledAttributes(attrs, new int[]{Android.R.attr.listDivider});
    mDivider = a.getDrawable(0);
    a.recycle();
}

public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
        boolean showLastDivider) {
    this(context, attrs);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

public DividerItemDecoration(Drawable divider) {
    mDivider = divider;
}

public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
        boolean showLastDivider) {
    this(divider);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
        RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    if (mDivider == null) {
        return;
    }
    if (parent.getChildPosition(view) < 1) {
        return;
    }

    if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
        outRect.top = mDivider.getIntrinsicHeight();
    } else {
        outRect.left = mDivider.getIntrinsicWidth();
    }
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mDivider == null) {
        super.onDrawOver(c, parent, state);
        return;
    }

    // Initialization needed to avoid compiler warning
    int left = 0, right = 0, top = 0, bottom = 0, size;
    int orientation = getOrientation(parent);
    int childCount = parent.getChildCount();

    if (orientation == LinearLayoutManager.VERTICAL) {
        size = mDivider.getIntrinsicHeight();
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
    } else { //horizontal
        size = mDivider.getIntrinsicWidth();
        top = parent.getPaddingTop();
        bottom = parent.getHeight() - parent.getPaddingBottom();
    }

    for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
        View child = parent.getChildAt(i);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getTop() - params.topMargin;
            bottom = top + size;
        } else { //horizontal
            left = child.getLeft() - params.leftMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }

    // show last divider
    if (mShowLastDivider && childCount > 0) {
        View child = parent.getChildAt(childCount - 1);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getBottom() + params.bottomMargin;
            bottom = top + size;
        } else { // horizontal
            left = child.getRight() + params.rightMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

private int getOrientation(RecyclerView parent) {
    if (parent.getLayoutManager() instanceof LinearLayoutManager) {
        LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
        return layoutManager.getOrientation();
    } else {
        throw new IllegalStateException(
                "DividerItemDecoration can only be used with a LinearLayoutManager.");
    }
}
}
6
gatlingxyz

Anstatt einen shape xml zu erstellen, ändern Sie die Teilerhöhe und -farbe. Sie können programmgesteuert wie erstellen

val divider = DividerItemDecoration(context,
        DividerItemDecoration.VERTICAL)

divider.setDrawable(ShapeDrawable().apply {
    intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)
    Paint.color = Color.RED // note: currently (support version 28.0.0), we can not use tranparent color here, if we use transparent, we still see a small divider line. So if we want to display transparent space, we can set color = background color or we can create a custom ItemDecoration instead of DividerItemDecoration. 
})

recycler_devices.addItemDecoration(divider)
5
Phan Van Linh

Ich habe das Gefühl, dass eine einfache, codebasierte Antwort benötigt wird, die kein XML verwendet

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);

ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());

int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);
shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);
shapeDrawableForDivider.setAlpha(0);

dividerItemDecoration.setDrawable(shapeDrawableForDivider);

recyclerView.addItemDecoration(dividerItemDecoration);
4
Boober Bunz

Zu spät, aber für GridLayoutManager verwende ich Folgendes:

public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
    private int space;

    public GridSpacesItemDecoration(int space) {
        this.space = space;
    }

    public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        var position = parent.GetChildLayoutPosition(view);

        /// Only for GridLayoutManager Layouts
        var manager = parent.GetLayoutManager() as GridLayoutManager;

        if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
            outRect.Top = space;

        if (position % 2 != 0) {
            outRect.Right = space;
        }

        outRect.Left = space;
        outRect.Bottom = space;
    }
}

Diese Arbeit für jede Spanne, die Sie haben.

Ollie.

4
Ollie Strevel

Ich habe eine Zeile im Listenelement wie unten hinzugefügt

<View
Android:id="@+id/divider"
Android:layout_width="match_parent"
Android:layout_height="1px"
Android:background="@color/dividerColor"/>

1px zeichnet die dünne Linie.

Wenn Sie den Teiler für die letzte Zeile ausblenden möchten, dann divider.setVisiblity(View.GONE); im onBindViewHolder für das letzte Listenelement.

4
Raja Peela

Wenn Sie den gleichen Platz für Elemente hinzufügen möchten, können Sie Kartenelementen am einfachsten einen oberen + linken Rand für RecycleView und einen rechten + unteren Rand hinzufügen.

dimens.xml

<resources>
    <dimen name="divider">1dp</dimen>
</resources>

list_item.xml

<CardView
 Android:layout_marginBottom="@dimen/divider"
 Android:layout_marginRight="@dimen/divider">
 ...
</CardView>

list.xml

<RecyclerView
 Android:paddingLeft="@dimen/divider"
 Android:paddingTop="@dimen/divider"
/>
4
limitium

Sie können mit programmatisch leicht hinzufügen.

Wenn Ihr Layout-Manager Linearlayout ist, können Sie Folgendes verwenden:

DividerItemDecoration ist eine RecyclerView.ItemDecoration, die als Trennlinie zwischen Elementen eines LinearLayoutManager verwendet werden kann. Es unterstützt sowohl die horizontale als auch die vertikale Ausrichtung.

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

Quelle

4
Beyaz
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);
            }
        }


    }
}

Dies fügt oben und unten (oder links und rechts) Platz hinzu. Dann können Sie es auf Ihre recyclerView einstellen.

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);
    }
}
3
wizChen

Eine sehr einfache Lösung ist RecyclerView-FlexibleDivider

Abhängigkeit hinzufügen:

compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'

Zu Ihrer Recyclingübersicht hinzufügen:

recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());

Und du bist fertig!

3
Cristan

1. Einer der Wege ist , indem wir die Kartenansicht und die Recycler-Ansicht zusammen verwenden , können wir leicht einen Effekt wie einen Teiler hinzufügen. Beispiel: https://developer.Android.com/training/material/lists-cards.html

2.und andere ist durch Hinzufügen der Ansicht als Teiler zu list_item_layout der Recycler-Ansicht .

        <View
            Android:id="@+id/view1"
            Android:layout_width="match_parent"
            Android:layout_height="1dp"
            Android:background="@color/colorAccent" />
3
vicky

Das RecyclerView ist ein bisschen anders als das ListView. Tatsächlich benötigt der RecyclerView eine ListView ähnliche Struktur. Zum Beispiel ein LinearLayout. Das LinearLayout hat Parameter zum Teilen jedes Elements. Im folgenden Code habe ich ein RecyclerView, das aus CardView Objekten innerhalb eines LinearLayout besteht, mit einer "Auffüllung", die etwas Platz zwischen Elementen einfügt. Machen Sie diesen Raum wirklich klein und Sie erhalten eine Linie.

Hier ist die Recycler-Ansicht in recyclerview_layout.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
    Android:layout_height="match_parent" Android:paddingLeft="@dimen/activity_horizontal_margin"
    Android:paddingRight="@dimen/activity_horizontal_margin"
    Android:paddingTop="@dimen/activity_vertical_margin"
    Android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ToDoList">

    <!-- A RecyclerView with some commonly used attributes -->
    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/todo_recycler_view"
        Android:scrollbars="vertical"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

</RelativeLayout>

Und hier ist, wie jedes Element aussieht (und aufgrund von Android als geteilt dargestellt wird: Auffüllen im LinearLayout, das alles umgibt.) In einer anderen Datei: cards_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical" Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    **Android:padding="@dimen/activity_vertical_margin"**>
    <!-- A CardView that contains a TextView -->
    <Android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/card_view"
        Android:layout_gravity="center"
        Android:layout_width="match_parent"
        Android:layout_height="100dp"
        Android:elevation="30dp"
        card_view:cardElevation="3dp">
            <TextView
                Android:id="@+id/info_text"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                />
    </Android.support.v7.widget.CardView>
</LinearLayout>
3
fiacobelli

Implementieren Sie eine eigene Version von RecyclerView.ItemDecoration

public class SpacingItemDecoration extends RecyclerView.ItemDecoration {
    private int spacingPx;
    private boolean addStartSpacing;
    private boolean addEndSpacing;

    public SpacingItemDecoration(int spacingPx) {
        this(spacingPx, false, false);
    }

    public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) {
        this.spacingPx = spacingPx;
        this.addStartSpacing = addStartSpacing;
        this.addEndSpacing = addEndSpacing;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (spacingPx <= 0) {
            return;
        }

        if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.top = spacingPx;
            } else {
                outRect.left = spacingPx;
            }
        }

        if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.bottom = spacingPx;
            } else {
                outRect.right = spacingPx;
            }
        }
    }

    private int getTotalItemCount(RecyclerView parent) {
        return parent.getAdapter().getItemCount();
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        } else {
            throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}
2
e.shishkin

PrimeAdapter

Mit PrimeAdapter kann die Behandlung von Teilern in RecyclerViews so einfach sein. Es bietet mehrere Funktionen und mehr Flexibilität beim Erstellen und Verwalten von Teilern.

Sie können einen Adapter wie folgt erstellen: (Informationen zur Verwendung in github finden Sie im vollständigen Dokument.)

val adapter = PrimeAdapter.with(recyclerView)
                    .setLayoutManager(LinearLayoutManager(activity))
                    .set()
                    .build(ActorAdapter::class.Java)

Nach dem Erstellen einer Adapterinstanz können Sie einfach einen Teiler hinzufügen, indem Sie Folgendes verwenden:

//----- default divider:
adapter.setDivider()

//----- divider with custom drawable:
adapter.setDivider(ContextCompat.getDrawable(context, R.drawable.divider))

//----- divider with custom color:
adapter.setDivider(Color.RED)

//----- divider with custom color and custom inset:
adapter.setDivider(Color.RED, insetLeft = 16, insetRight = 16)

//----- deactivate dividers:
adapter.setDivider(null)

enter image description here

1
aminography

Verwenden Sie diese Klasse, um einen Teiler in Ihrem RecyclerView festzulegen.

 public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

        private int spanCount;
        private int spacing;
        private boolean includeEdge;

        public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
            this.spanCount = spanCount;
            this.spacing = spacing;
            this.includeEdge = includeEdge;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view); // item position
            int column = position % spanCount; // item column

            if (includeEdge) {
                outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
                outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

                if (position < spanCount) { // top Edge
                    outRect.top = spacing;
                }
                outRect.bottom = spacing; // item bottom
            } else {
                outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
                outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
                if (position >= spanCount) {
                    outRect.top = spacing; // item top
                }
            }
        }
    }
1
Makvin
public class VerticalItemDecoration extends RecyclerView.ItemDecoration {

private boolean verticalOrientation = true;
private int space = 10;

public VerticalItemDecoration(int value, boolean verticalOrientation) {
    this.space = value;
    this.verticalOrientation = verticalOrientation;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                           RecyclerView.State state) {
    //skip first item in the list
    if (parent.getChildAdapterPosition(view) != 0) {
        if (verticalOrientation) {
            outRect.set(space, 0, 0, 0);
        } else if (!verticalOrientation) {
            outRect.set(0, space, 0, 0);
        }
    }
}
}

mCompletedShippingRecyclerView.addItemDecoration(new VerticalItemDecoration(20,false)); 
1
Amardeep

Ich habe eine sehr einfache Möglichkeit, einen Teiler in RecyclerView hinzuzufügen. Verwenden Sie einen benutzerdefinierten Adapter, um das Layout der Recycler-Ansicht zu ändern, und fügen Sie dann zusammen mit den Elementen der Recycler-Ansicht LinearLayout mit einer Hintergrundfarbe (die die Teilerfarbe ist) und einer Höhe von 1 dpi (oder gemäß Ihren Anforderungen) und einer Breite hinzu, die den übergeordneten Elementen entspricht .

Hier ist ein Beispielcode.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="match_parent"
Android:layout_height="match_parent">

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="horizontal"
    Android:padding="18dp">

    <TextView
        Android:id="@+id/list_row_SNO"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight=".8"
        Android:layout_gravity="end"
        Android:text="44."
        Android:textAlignment="center"
        Android:textSize="24sp"
        Android:textColor="@color/colorBlack"
        Android:fontFamily="sans-serif-condensed" />

    <TextView
        Android:id="@+id/list_row_Heading"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight=".2"
        Android:layout_gravity="start"
        Android:text="Student's application for leave and this what"
        Android:textAlignment="textStart"
        Android:textSize="24sp"
        Android:textColor="@color/colorBlack"
        Android:fontFamily="sans-serif-condensed" />

</LinearLayout>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="1dp"
    Android:background="@color/colorHighlight">
</LinearLayout>
1
Nabajyoti Das

RecyclerView bietet keine einfache Oberfläche zum Zeichnen von Teilern von Listen. Tatsächlich bietet es uns jedoch eine viel flexiblere Möglichkeit, Trennlinien zu zeichnen. Wir verwenden RecyclerView.ItemDecoration , um die Fliesen von RecyclerView mit Trennwänden oder anderen Elementen zu dekorieren. Deshalb heißt es auch ItemDecoration.

Wie in Meterial Design Guidelines beschrieben:

Der Teiler befindet sich innerhalb der Grundlinie der Kachel.

Wenn Sie also die Richtlinien für das Materialdesign befolgen möchten, benötigen Sie keinen zusätzlichen Platz, um die Trennlinien zu zeichnen. Zeichne sie einfach auf die Fliesen. Sie haben jedoch das Recht, alles zu tun, was Sie möchten. Also habe ich eine implementiert, mit der Sie sowohl Einfügungen setzen als auch auf/unter die Kacheln zeichnen können.

public class InsetDivider extends RecyclerView.ItemDecoration {

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Paint mPaint;
    // in pixel
    private int mDividerHeight;
    // left inset for vertical list, top inset for horizontal list
    private int mFirstInset;
    // right inset for vertical list, bottom inset for horizontal list
    private int mSecondInset;
    private int mColor;
    private int mOrientation;
    // set it to true to draw divider on the tile, or false to draw beside the tile.
    // if you set it to false and have inset at the same time, you may see the background of
    // the parent of RecyclerView.
    private boolean mOverlay;

    private InsetDivider() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
    }

    public int getDividerHeight() {
        return mDividerHeight;
    }

    public void setDividerHeight(int dividerHeight) {
        this.mDividerHeight = dividerHeight;
    }

    public int getFirstInset() {
        return mFirstInset;
    }

    public void setFirstInset(int firstInset) {
        this.mFirstInset = firstInset;
    }

    public int getSecondInset() {
        return mSecondInset;
    }

    public void setSecondInset(int secondInset) {
        this.mSecondInset = secondInset;
    }

    public int getColor() {
        return mColor;
    }

    public void setColor(int color) {
        this.mColor = color;
        mPaint.setColor(color);
    }

    public int getOrientation() {
        return mOrientation;
    }

    public void setOrientation(int orientation) {
        this.mOrientation = orientation;
    }

    public boolean getOverlay() {
        return mOverlay;
    }

    public void setOverlay(boolean overlay) {
        this.mOverlay = overlay;
    }

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

    protected void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft() + mFirstInset;
        final int right = parent.getWidth() - parent.getPaddingRight() - mSecondInset;
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {
                continue;
            }
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int bottom;
            final int top;
            if (mOverlay) {
                bottom = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
                top = bottom - mDividerHeight;
            } else {
                top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
                bottom = top + mDividerHeight;
            }
            c.drawRect(left, top, right, bottom, mPaint);
        }
    }

    protected void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop() + mFirstInset;
        final int bottom = parent.getHeight() - parent.getPaddingBottom() - mSecondInset;
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {
                continue;
            }
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
            final int right;
            final int left;
            if (mOverlay) {
                right = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
                left = right - mDividerHeight;
            } else {
                left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
                right = left + mDividerHeight;
            }
            c.drawRect(left, top, right, bottom, mPaint);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOverlay) {
            super.getItemOffsets(outRect, view, parent, state);
            return;
        }

        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDividerHeight);
        } else {
            outRect.set(0, 0, mDividerHeight, 0);
        }
    }

    /**
     * Handy builder for creating {@link InsetDivider} instance.
     */
    public static class Builder {

        private Context mContext;
        private int mDividerHeight;
        private int mFirstInset;
        private int mSecondInset;
        private int mColor;
        private int mOrientation;
        private boolean mOverlay = true; // set default to true to follow Material Design Guidelines

        public Builder(Context context) {
            mContext = context;
        }

        public Builder dividerHeight(int dividerHeight) {
            mDividerHeight = dividerHeight;
            return this;
        }

        public Builder insets(int firstInset, int secondInset) {
            mFirstInset = firstInset;
            mSecondInset = secondInset;
            return this;
        }

        public Builder color(@ColorInt int color) {
            mColor = color;
            return this;
        }

        public Builder orientation(int orientation) {
            mOrientation = orientation;
            return this;
        }

        public Builder overlay(boolean overlay) {
            mOverlay = overlay;
            return this;
        }

        public InsetDivider build() {
            InsetDivider insetDivider = new InsetDivider();

            if (mDividerHeight == 0) {
                // Set default divider height to 1dp.
                 insetDivider.setDividerHeight(mContext.getResources().getDimensionPixelSize(R.dimen.divider_height));
            } else if (mDividerHeight > 0) {
                insetDivider.setDividerHeight(mDividerHeight);
            } else {
                throw new IllegalArgumentException("Divider's height can't be negative.");
            }

            insetDivider.setFirstInset(mFirstInset < 0 ? 0 : mFirstInset);
            insetDivider.setSecondInset(mSecondInset < 0 ? 0 : mSecondInset);

            if (mColor == 0) {
                throw new IllegalArgumentException("Don't forget to set color");
            } else {
                insetDivider.setColor(mColor);
            }

            if (mOrientation != InsetDivider.HORIZONTAL_LIST && mOrientation != InsetDivider.VERTICAL_LIST) {
                throw new IllegalArgumentException("Invalid orientation");
            } else {
                insetDivider.setOrientation(mOrientation);
            }

            insetDivider.setOverlay(mOverlay);

            return insetDivider;
        }
    }
}

Und du kannst es so benutzen:

ItemDecoration divider = new InsetDivider.Builder(this)
                            .orientation(InsetDivider.VERTICAL_LIST) 
                            .dividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height))
                            .color(getResources().getColor(R.color.colorAccent))
                            .insets(getResources().getDimensionPixelSize(R.dimen.divider_inset), 0)
                            .overlay(true)
                            .build(); 

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(divider);

Ich habe auch eine Demo-App geschrieben, die beschreibt, wie ItemDecoration implementiert und verwendet wird. Sie können sich mein GitHub-Repo Dividers-For-RecyclerView ansehen. Es gibt drei Implementierungen:

  • UnderneathDivider
  • OverlayDivider
  • InsetDivider
1
Jiaheng

Hier ist meine faulen Ansatz, aber es funktioniert: Wickeln Sie die CardView in ein Layout und setzen Sie einen Abstand/Rand auf das übergeordnete Layout, um den Teiler zu imitieren, und zwingen Sie den normalen Teiler auf Null

list_item.xml

<LinearLayout
    Android:id="@+id/entry_item_layout_container"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    Android:paddingBottom="<divider_size>" > // this is the divider
    <CardView
        Android:layout_width="<width_size>"
        Android:layout_height="<height_size>">
        ...
    </CardView>
</LinearLayout

list.xml

<RecyclerView
 Android:divider="@null"
 Android:layout_width="<width_size>"
 Android:layout_height="<height_size>"
 ...
/>
0
kip2