Come aggiungere divisori e spazi tra gli elementi in RecyclerView?


938

Questo è un esempio di come avrebbe potuto essere fatto in precedenza nella ListViewclasse, usando i parametri divisore e dividerHeight :

<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"/>

Tuttavia, non vedo tale possibilità in RecyclerViewclasse.

<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"/>

In tal caso, è corretto definire i margini e / o aggiungere una vista divisoria personalizzata direttamente nel layout di un elemento dell'elenco o esiste un modo migliore per raggiungere il mio obiettivo?



@EyesClear Aggiungi elementi <TextView /> un altro xml e utilizzalo nell'elenco Stessa attività.
Amitsharma,

7
C'è una classe nella com.homeretailgroup.argos.android.view.decorators.DividerItemDecorationmRecyclerView.addItemDecoration(new DividerItemDecoration(activity, LinearLayoutManager.VERTICAL));
libreria di

È possibile aggiungere un margine inferiore all'elemento dell'elenco per gli elenchi verticali e forse può essere utilizzato come divisore?
risw67 del

Il modo più semplice è aggiungere margini superiore / inferiore attorno al primo elemento nella riga dell'adattatore. Android: layout_marginBottom = "4DP". (Nota che l'aggiunta dei margini al layout principale non lo taglierà.)
pstorli

Risposte:


1227

Aggiornamento di ottobre 2016

La versione 25.0.0 della libreria di supporto Android ha introdotto la DividerItemDecorationclasse:

DividerItemDecoration è un RecyclerView.ItemDecoration che può essere utilizzato come divisore tra gli elementi di a LinearLayoutManager. Supporta entrambi HORIZONTALe VERTICALorientamenti.

Uso:

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

Risposta precedente

Alcune risposte utilizzano metodi che da allora sono diventati obsoleti o non forniscono una soluzione completa, quindi ho provato a fare un riassunto breve e aggiornato.


Diversamente ListView, la RecyclerViewclasse non ha parametri relativi al divisore. Invece, è necessario estendere ItemDecoration, RecyclerViewla classe interna di a:

Un ItemDecorationconsente all'applicazione di aggiungere un disegno speciale e un offset di layout a viste di elementi specifici dal set di dati dell'adattatore. Questo può essere utile per disegnare divisori tra elementi, luci, bordi del raggruppamento visivo e altro.

Tutti ItemDecorationssono disegnati nell'ordine in cui sono stati aggiunti, prima che il punto di vista voce (a onDraw()) e dopo le voci (in onDrawOver ( Canvas, RecyclerView, RecyclerView.State).

Vertical spaziatura ItemDecoration

Estendi ItemDecoration, aggiungi un costruttore personalizzato che occupa spazio heightcome parametro e ignora il getItemOffsets()metodo:

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

Se non si desidera inserire spazio sotto l'ultimo elemento, aggiungere la seguente condizione:

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

Nota: è possibile anche modificare outRect.top, outRect.lefte outRect.rightle proprietà per l'effetto desiderato.

Divisore ItemDecoration

Estendi ItemDecoratione sostituisci onDraw()metodo:

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

Puoi chiamare il primo costruttore che utilizza gli attributi predefiniti del divisore Android o il secondo che utilizza il tuo drawable, ad esempio 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>

Nota: se vuoi che il divisore sia disegnato sopra i tuoi oggetti, sostituisci onDrawOver()invece il metodo.

uso

Per utilizzare la nuova classe aggiungi VerticalSpaceItemDecorationo DividerSpaceItemDecorationa RecyclerView, ad esempio nel onCreateView()metodo del tuo frammento :

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

C'è anche la biblioteca di Lucas Rocha che dovrebbe semplificare il processo di decorazione degli oggetti. Non l'ho provato però.

Tra le sue caratteristiche ci sono:

  • Una collezione di decorazioni per articoli in stock tra cui:
  • Spaziatura degli elementi Divisori orizzontali / verticali.
  • Voce di elenco

3
@droppin_science Correggimi se sbaglio, ma non creo alcun oggetto onDraw(). Ho appena fatto riferimento a istanze già esistenti.
EyesClear

1
Mi chiedo se sia una buona idea usare Paint invece di creare un disegno? Allora posso chiamare canvas.drawLine(startX, startY, stopX, stopY, mPaint)in onDrawOver? Qualche differenza di prestazioni?
Arst,

1
Solo un commento informativo: aggiungi sempre lo spazio all'ultimo elemento se prevedi di aggiungere elementi più avanti nell'elenco. Se non lo fai, quando aggiungi un oggetto, non avrà lo spazio. Grazie per il VerticalSpace!
Tsuharesu,

24
DividerItemDecoration come mostrato sopra non funzionerà se gli oggetti sono completamente opachi, i divisori verranno sovrastati dagli oggetti. In tal caso è necessario sovrascrivere anche getItemOffsets () e aggiungere l'offset inferiore a outRect in modo che il divisore finisca fuori dall'elemento. In alternativa, puoi sovrascrivere onDrawOver () invece di onDraw () per disegnare il divisore dopo l'elemento.
jpop,

115
Un'intera pagina di codice per aggiungere semplicemente il divisore a recyclerView è la risposta migliore. Peccato per te, google.
attent7j

480

Basta aggiungere

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

Inoltre potrebbe essere necessario aggiungere la dipendenza
compile 'com.android.support:recyclerview-v7:27.1.0'

MODIFICARE:

Per personalizzarlo un po 'puoi aggiungere un disegno personalizzabile:

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

Sei libero di utilizzare qualsiasi disegno personalizzato, ad esempio:

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

L'attività non è necessaria. Il contesto è abbastanza
mac229

Questa deve essere la risposta corretta. Per favore, cambia getActivity nel solo contesto.
Jhon Fredy Trujillo Ortega

Inoltre è meglio ottenere l'orientamento dal LayoutManager.
dal

Grazie! Inoltre puoi usare il Configurationdivisore verticale:if (orientation == Configuration.ORIENTATION_LANDSCAPE) { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL)); } else { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));}
AlexS

3
Bella risposta, ma aggiunge un divisore anche dopo l'ultimo elemento.
CoolMind

256

Potrei rivolgere la tua attenzione a questo particolare file su Github di Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

È il file di esempio DividerItemDecoration.java "estratto direttamente dalle demo di supporto". ( Https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

Dopo aver importato questo file nel mio progetto sono stato in grado di ottenere le linee divisorie e di aggiungerlo come elemento decorativo alla vista del riciclatore.

Ecco come appare il mio onCreateView nel mio frammento contenente il 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;
}

Sono sicuro che si può fare uno stile aggiuntivo, ma è un punto di partenza. :)


Come si aggiungono quelli sostituiti: "footerDividersEnabled", "headerDividersEnabled", "listSelector", "fastScrollEnabled", "smoothScrollbar", "textFilterEnabled"?
sviluppatore Android

Qualche input su Come mettere lo styling?
nizam.sp,

per dare uno stile a questa soluzione devi sovrascrivere l'attributo "android: listDivider" nel tuo tema
Pavel Dudka il

1
Divider non funziona con RecyclerView. Devi usare RecyclerView.itemDecoration. Vedi questa risposta: stackoverflow.com/a/27664023/2311451
Cocorico

3
perché il divisore espande l'intera larghezza dell'articolo? come visualizzare come nelle specifiche google.com/design/spec/components/lists.html#lists-specs
chip

156

ItemDecorationImplementazione semplice per spazi uguali tra tutti gli elementi.

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

sto ottenendo lo spazio, ma come posso ottenere un divisore
Pankaj Nimgade,

26
getChildPositionè ora deprecato, getChildAdapterPositionpuò invece essere utilizzato.
EyesClear,

4
Non dimenticare (come ho fatto io) di rimuovere la chiamata super.getItemOffsets, altrimenti i tuoi offset verranno sovrascritti.
jayeffkay,

@EyesClear non dovrebbe getChildLayoutPositionessere usato?
Avinash R,

3
questo implementa la spaziatura in pixel?
filthy_wizard,

108

Quello semplice è impostare il colore di sfondo per RecyclerView e il colore di sfondo diverso per gli articoli. Ecco un esempio ...

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

e l' oggetto TextView (può essere qualsiasi cosa però) con margine inferiore "x" dp o px.

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

Il risultato ...

inserisci qui la descrizione dell'immagine


2
Che trucco! deve solo mantenere l'elenco bianco durante il caricamento.
Hamzeh Soboh,

36
Attenzione al sovraccarico!
Sem

@shem potresti elaborare?
RominaV,

7
Quando si disegna in Android due livelli uno sopra l'altro (lo sfondo dell'attività, lo sfondo della vista del riciclo e lo sfondo della vista dell'elemento) - Android disegnandoli tutti, anche quelli che non sono visibili agli utenti. Questo ha chiamato overdraw e potrebbe influire sulle tue prestazioni, maggiori informazioni qui: youtube.com/watch?v=T52v50r-JfE
shem

41

Penso che usare un semplice divisore ti aiuterà

ad aggiungere un divisore ad ogni elemento:
1- Aggiungi questo alla directory disegnabile 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- Crea classe SimpleDividerItemDecoration
Ho usato questo esempio per definire questa classe:
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- Nell'attività o frammento che usando RecyclerView, all'interno di onCreateView aggiungi questo:

@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- Per aggiungere la spaziatura tra gli articoli
è sufficiente aggiungere la proprietà di riempimento alla vista degli oggetti

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

Come faccio a farlo funzionare per GridLayoutManager, per mostrare anche i divisori verticali tra le celle?
sviluppatore Android il

2
resources.getDrawable () è ora obsoleto. Puoi passare nel contesto e utilizzare ContextCompat.getDrawable (context, R.drawable.line_divider)
Eric B.

36

Come ho impostato ItemAnimators. Il ItemDecoratornon entrare o uscire insieme con l'animazione.

Ho semplicemente finito per avere una linea di visualizzazione nel mio file di layout di visualizzazione degli articoli di ciascun articolo. Ha risolto il mio caso. DividerItemDecorationsembrava troppo stregoneria per un semplice divisore.

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

Hai ragione. Le animazioni non funzionano con ItemDecoration. Non sono sicuro del perché, ma senza che io specifichi nulla, ricevo animazioni e trovo molto fastidioso e brutto che le linee create da ItemDecoration non seguano. Quindi userò una soluzione come la tua.
Michel,

Come hai gestito l'ultimo articolo?
oldergod,

@oldergod. Hai indicato il punto di dolore giusto. Innanzitutto vorrei essere d'accordo sul fatto che un progetto abbia anche un divisore sull'ultimo elemento. Ma se non lo vuoi. assegnare un id a questa vista e nasconderlo in bindView se la posizione è ultima.
Javanator,

@Javanator Vedo bene, lo stesso approccio che ho adottato. Grazie.
Oldergod,

il più semplice è il migliore
hyyou2010,

27

Questo è semplice, non è necessario un codice così complicato

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

Aggiungi questo nel tuo drawable: 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

Dal momento che non esiste un modo giusto per implementarlo correttamente ma utilizzando Material Design, ho appena fatto il seguente trucco per aggiungere direttamente un divisore all'elemento dell'elenco:

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>

DividerItemDecoration smette di funzionare dopo che ho ricevuto alcune informazioni sull'elevazione del design del materiale (per ottenere lo stesso effetto come in Posta in arrivo); è diventato troppo complicato per una cosa semplice. Questa soluzione è semplice e funziona.
DenisGL,

21

Il modo in cui sto gestendo la vista Divider e anche Divider Insets è aggiungendo un'estensione RecyclerView.

1.

Aggiungi un nuovo file di estensione nominando Visualizza o RecyclerView:

RecyclerViewExtension.kt

e aggiungi il setDividermetodo di estensione all'interno del file RecyclerViewExtension.kt.

/*
* RecyclerViewExtension.kt
* */
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView


fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {
    val divider = DividerItemDecoration(
        this.context,
        DividerItemDecoration.VERTICAL
    )
    val drawable = ContextCompat.getDrawable(
        this.context,
        drawableRes
    )
    drawable?.let {
        divider.setDrawable(it)
        addItemDecoration(divider)
    }
}

2.

Crea un file di risorse Drawable all'interno del drawablepacchetto come recycler_view_divider.xml:

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="10dp"
    android:insetRight="10dp">

    <shape>
        <size android:height="0.5dp" />
        <solid android:color="@android:color/darker_gray" />
    </shape>

</inset>

dove è possibile specificare il margine sinistro e destro su android:insetLefte android:insetRight.

3.

Nella tua attività o frammento in cui è inizializzato RecyclerView, puoi impostare il disegno personalizzabile chiamando:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

Saluti 🍺

Riga RecyclerView con divisore.


16

Se qualcuno sta cercando di aggiungere, diciamo, una spaziatura 10dp tra gli elementi, puoi farlo impostando un disegno su DividerItemDecoration:

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

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

Dove si divider_10dptrova una risorsa estraibile contenente:

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



11

Per coloro che cercano solo spazi tra gli elementi nel RecyclerViewmio approccio vedi dove ottieni uguali spazi tra tutti gli oggetti, tranne nel primo e nell'ultimo elemento in cui ho dato un'imbottitura più grande. Applico solo l'imbottitura a sinistra / a destra in orizzontale LayoutManagere in alto / in basso in verticale LayoutManager.

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

Aggiungi un margine alla tua vista, ha funzionato per me.

android:layout_marginTop="10dp"

Se vuoi solo aggiungere una spaziatura uguale e vuoi farlo in XML , imposta la paddingtua RecyclerViewe uguale quantità layoutMargindell'oggetto che gonfia nel tuo RecyclerViewe lascia che il colore di sfondo determini il colore della spaziatura.


3
Anche se funzionerà, questa non è la risposta corretta, ad esempio, perché questo non risolve il problema senza fare cose extra al layout delle righe, inoltre, nella parte superiore apparirà il margine x1, tra le righe del margine x2.
Sreekanth Karumanaghat,

Questa non è una buona idea perché overscrollall'effetto tirando alla fine dell'elenco verrà applicata un'imbottitura non necessaria a quando viene applicata l'imbottituraRecyclerView
AeroEchelon,

È meglio avvolgere il layout dell'elemento in una libreria di supporto CardView in modo da poter controllare altri attributi come altezza / ombra, ecc.: <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" card_view:cardElevation="4dp" <!-- your item's XML here --> </android.support.v7.widget.CardView>
kip2

11
  • Ecco un semplice trucco per aggiungere un divisore
  • Aggiungi uno sfondo al layout del tuo articolo riciclatore come segue

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

Crea il seguente shape_border.xml nella cartella disegnabile

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

Ecco il risultato finale: un RecyclerView con divisore.

Ecco il risultato finale: un RecyclerView con divisore.


1
Questo non è un approccio preferito. Anche se la risposta @EyesClear avvia int in onDraw e parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1probabilmente dovrebbe essere parent.getChildAdapterPosition(view) > 0con il outRect.bottom = mVerticalSpaceHeightdivenire outRect.top = mVerticalSpaceHeightdovrebbe essere la risposta accettata.
droppin_science

@droppin_science - Non puoi trascurarlo dicendo solo che questo non è un approccio preferito, mi dà risultati accurati come previsto, guardo anche la risposta di EyesClear ma quella risposta è troppo complicata per un semplice divisore, tuttavia se è necessario fai qualche decorazione extra con l'oggetto, quindi quella può essere la risposta accettata.
turbandroid

Per gli elettori in ribasso, questa risposta è stata data nel momento in cui non c'erano classi ufficiali per DividerItemDecoration, quindi basta confrontare il divario temporale tra questa risposta e la seguente risposta data da Leo Droidcoder. :)
turbandroid

9

Ho modificato DividerItemDecoration da una versione precedente e l'ho semplificato per adattarlo al mio caso d'uso, e l'ho anche modificato per disegnare i divisori nel modo in cui sono disegnati in ListView, incluso un divisore dopo l'ultimo elemento dell'elenco. Questo gestirà anche le animazioni verticali di ItemAnimator:

1) Aggiungi questa classe al tuo progetto:

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) Aggiungi il decoratore al tuo RecylerView:

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

Corretto, è pensato per un LinearLayoutManager. Puoi prendere l'idea alla base per adattarla a un GridLayoutManager.
Impara OpenGL ES l'

8

Invece di creare un shape xmlper cambiare l'altezza e il colore del divisore. Puoi creare come programmaticamente

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)

questa è una risposta utile
taha

7

Tratto da una ricerca su Google, aggiungi questo ItemDecoration al tuo RecyclerView:

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

Funziona bene solo per LinearLayoutManager. Cosa si dovrebbe fare per GridLayoutManager?
sviluppatore Android il

6

Questo link ha funzionato come un incantesimo per me:

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

Quindi nella tua attività:

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

O questo se stai usando un frammento:

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

1
Funziona bene, ma non mostra il divisore nell'ultimo elemento dell'elenco. Ne ho bisogno in questo modo: mShowFirstDivider = false, mShowLastDivider = true, ma non funzionerà. Qualche idea sul perché?
risolto l'

Questo non può gestire bene GridLayoutManager.
sviluppatore Android il

6

Possiamo decorare gli oggetti usando vari decoratori collegati al recyclerview come DividerItemDecoration:

Usa semplicemente il seguente ... tratto dalla risposta di 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);
    }
}

} e quindi utilizzare quanto sopra come segue

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

In questo modo verranno visualizzati i divisori tra ciascun elemento nell'elenco come mostrato di seguito:

inserisci qui la descrizione dell'immagine

E per coloro che sono alla ricerca di maggiori dettagli può consultare questa guida Utilizzo di RecyclerView _ CodePath Android Cliffnotes

Alcune risposte qui suggeriscono l'uso dei margini, ma il problema è che: se aggiungi i margini superiore e inferiore, appariranno entrambi aggiunti tra gli elementi e saranno troppo grandi. Se aggiungi solo uno dei due, non ci sarà margine né all'inizio né alla fine dell'intero elenco. Se aggiungi metà della distanza in alto, metà in basso, i margini esterni saranno troppo piccoli.

Pertanto, l'unica soluzione esteticamente corretta è il divisore che il sistema sa dove applicare correttamente: tra gli elementi ma non sopra o sotto gli elementi.

Per favore fatemi sapere di eventuali dubbi nei commenti qui sotto :)


1
Questo non dimostra l' DividerItemDecorationaspetto del codice.
IgorGanapolsky,

1
È una classe AOSP, ho estratto
Anudeep Samaiya

Non funziona bene: non gestisce righe di diversa altezza e non mostra un divisore verticale per le griglie
sviluppatore Android

5

Troppo tardi ma per GridLayoutManagerquesto uso:

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

Questo lavoro per qualsiasi conteggio di span che hai.

Ollie.


Riguardo allo spazio superiore, come lo cambieresti per supportare anche FlexboxLayoutManager?
sviluppatore Android

5

È possibile aggiungere con programmaticamente facilmente.

Se Layout Manager è Linearlayout, è possibile utilizzare:

DividerItemDecoration è un RecyclerView.ItemDecoration che può essere utilizzato come divisore tra gli elementi di un LinearLayoutManager. Supporta entrambi gli orientamenti ORIZZONTALE e VERTICALE.

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

fonte


5

Sento che c'è bisogno di una risposta semplice e basata su codice che non usi XML

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

Se si desidera aggiungere lo stesso spazio per gli oggetti, il modo più semplice è quello di aggiungere un'imbottitura superiore + sinistra per RecycleView e margini + destra in basso per gli elementi delle carte.

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

Ho aggiunto una riga nella voce di elenco come di seguito

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

1px disegnerà la linea sottile.

Se si desidera nascondere il divisore per l'ultima riga, quindi divider.setVisiblity(View.GONE);su onBindViewHolder per l'ultimo elemento dell'elenco.


1
Preferisco questo, gli altri sono troppo complicati.
Sam Chen,

3

Il RecyclerViewè un po 'diverso dal ListView. In realtà, ha RecyclerViewbisogno di una ListViewstruttura simile in esso. Ad esempio, a LinearLayout. L' LinearLayoutha parametri del dividendo ciascun elemento. Nel codice qui sotto ho un RecyclerViewcompreso di CardViewoggetti all'interno di unLinearLayout di un "padding" che metterà un po 'di spazio tra gli oggetti. Rendi quello spazio davvero piccolo e ottieni una linea.

Ecco la vista Riciclatore 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>

Ed ecco come appare ogni elemento (e mostra come diviso a causa dell'androide: riempimento nel LinearLayout che circonda tutto.) In un altro file: 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

Una soluzione davvero semplice è usare RecyclerView-FlexibleDivider

Aggiungi dipendenza:

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

Aggiungi al tuo recyclerview:

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

E hai finito!


funziona come un fascino ... devo amare la condivisione open source.
Billy,

3

1.One of the Way è usando insieme la visualizzazione di cardview e recycler possiamo facilmente aggiungere effetti come il divisore. ex. https://developer.android.com/training/material/lists-cards.html

2.e altro è aggiungendo la vista come divisore a list_item_layout della vista riciclatore .

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

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

Questo aggiungerà spazio in ogni elemento in alto e in basso (o a sinistra e a destra), quindi puoi impostarlo sul tuo 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);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.