1127 Stimmen

Wie man Trennlinien und Abstände zwischen Elementen in RecyclerView hinzufügt

Dies ist ein Beispiel dafür, wie es vorher in der ListView-Klasse gemacht werden konnte, unter Verwendung der Parameter divider und dividerHeight:

Ich sehe jedoch keine solche Möglichkeit in der RecyclerView-Klasse.

In diesem Fall ist es okay, Margins zu definieren und/oder eine benutzerdefinierte Trennlinie direkt in das Layout eines Listenelements hinzuzufügen oder gibt es einen besseren Weg, um mein Ziel zu erreichen?

12voto

turbandroid Punkte 2256
  • Hier ist ein einfacher Hack, um einen Trennstrich hinzuzufügen

  • Fügen Sie einfach einen Hintergrund zum Layout Ihres Recycler-Elements wie folgt hinzu

Erstellen Sie die folgende shape_border.xml Datei im drawable-Ordner:

Hier ist das Endergebnis - ein RecyclerView mit Trennstrich.

Hier ist das Endergebnis - ein RecyclerView mit Trennstrich.

11voto

Kevin Grant Punkte 2281

Dies löst das Problem tatsächlich nicht, aber als vorübergehender Workaround können Sie die useCompatPadding Eigenschaft auf der Karte in Ihrem XML-Layout festlegen, damit sie genauso gemessen wird wie auf Versionen vor Lollipop.

card_view:cardUseCompatPadding="true"

9voto

Learn OpenGL ES Punkte 4468

Ich habe den DividerItemDecoration von einem älteren Gist abgezweigt und vereinfacht, um ihn an meinen Anwendungsfall anzupassen, und ich habe ihn auch modifiziert, um die Trennlinien so zu zeichnen, wie sie in ListView gezeichnet werden, einschließlich einer Trennlinie nach dem letzten Listenelement. Dies wird auch vertikale ItemAnimator-Animationen behandeln:

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("Nur mit vertikalen Listen verwendbar");
    }

    @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 muss eine Instanz von LinearLayoutManager sein");
        return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
    }
}

2) Fügen Sie dem RecyclerView den Dekorierer hinzu:

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

8voto

Nerdy Bunz Punkte 5350

Ich habe das Gefühl, dass es eine Notwendigkeit für eine einfache, codebasierte Antwort gibt, 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);

Ich liebe diese Antwort so sehr, dass ich sie als single-expression Kotlin-Antwort umgeschrieben habe:

recyclerView.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL).also { deco ->
    with (ShapeDrawable(RectShape())){
        intrinsicHeight = (resources.displayMetrics.density * 24).toInt()
        alpha = 0
        deco.setDrawable(this)
    }
})

Dies bewirkt dasselbe wie @Nerdy's Originalantwort, es setzt jedoch die Höhe des Trennelements auf 24dp anstelle eines Prozentsatzes der Höhe eines anderen Ansichtselements.

7voto

Westy92 Punkte 14901

Hier ist eine Dekoration, die es Ihnen ermöglicht, einen Abstand zwischen Elementen sowie einen Abstand an den Rändern festzulegen. Dies funktioniert für Layouts sowohl in HORIZONTAL als auch in VERTIKAL.

class LinearSpacingDecoration(
    @Px private val itemSpacing: Int,
    @Px private val edgeSpacing: Int = 0
): RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val count = parent.adapter?.itemCount ?: 0
        val position = parent.getChildAdapterPosition(view)
        val leading = if (position == 0) edgeSpacing else itemSpacing
        val trailing = if (position == count - 1) edgeSpacing else 0
        outRect.run {
            if ((parent.layoutManager as? LinearLayoutManager)?.orientation == LinearLayout.VERTICAL) {
                top = leading
                bottom = trailing
            } else {
                left = leading
                right = trailing
            }
        }
    }
}

Verwendung:

recyclerView.addItemDecoration(LinearSpacingDecoration(itemSpacing = 10, edgeSpacing = 20))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X