Question Comment ajouter des séparations et des espaces entre les éléments dans RecyclerView?


Ceci est un exemple de comment cela aurait pu être fait précédemment dans le ListView classe, en utilisant le diviseur et dividerHeight paramètres:

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

Cependant, je ne vois pas une telle possibilité dans le RecyclerView classe.

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

Dans ce cas, est-il acceptable de définir des marges et / ou d'ajouter une vue de division personnalisée directement dans la disposition d'un élément de liste ou existe-t-il un meilleur moyen d'atteindre mon objectif?


687
2017-07-07 20:01


origine


Réponses:


Mise à jour d'octobre 2016

La version 25.0.0 d'Android Support Library a été introduite DividerItemDecoration classe:

DividerItemDecoration est un RecyclerView.ItemDecoration qui peut être utilisé comme un séparateur entre les éléments d'un LinearLayoutManager. Il prend en charge les orientations HORIZONTALES et VERTICALES.

Usage:

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

Réponse précédente

Certaines réponses utilisent soit des méthodes qui sont depuis devenues obsolètes, soit ne donnent pas une solution complète, alors j'ai essayé de faire une courte mise à jour.


contrairement à ListView, la RecyclerView La classe n'a pas de paramètres liés au diviseur. Au lieu de cela, vous devez étendre ItemDecoration, une RecyclerViewde la classe interne:

Un ItemDecoration permet à l'application d'ajouter un dessin spécial et un décalage de mise en page à des vues d'éléments spécifiques à partir de l'ensemble de données de l'adaptateur. Cela peut être utile pour dessiner des séparateurs entre les éléments, les points saillants, les limites de regroupement visuel et plus encore.

Toutes les décorations d'article sont dessinées dans l'ordre dans lequel elles ont été ajoutées, avant les vues de l'élément (dans onDraw ()) et après les éléments (dans onDrawOver (Canvas, RecyclerView, RecyclerView.State).

Espacement vertical ItemDecoration

Étendre ItemDecoration, ajoutez un constructeur personnalisé qui prend la taille de l'espace comme paramètre et remplace getItemOffsets() méthode:

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

Si vous ne souhaitez pas insérer d'espace sous le dernier élément, ajoutez la condition suivante:

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

Note: vous pouvez également modifier outRect.top, outRect.left et outRect.right propriétés pour l'effet désiré.

Diviseur ItemDecoration

Étendre ItemDecoration et passer outre onDraw() méthode:

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

Vous pouvez appeler le premier constructeur qui utilise les attributs de diviseur Android par défaut ou le second qui utilise votre propre dessin, par exemple 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>

Note: si vous voulez que le diviseur soit dessiné plus de vos articles, remplacez onDrawOver() méthode à la place.

Usage

Pour utiliser votre nouvelle classe ajouter VerticalSpaceItemDecoration ou DividerSpaceItemDecoration à RecyclerView, par exemple dans votre fragment onCreateView() méthode:

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

Il y a aussi La bibliothèque de Lucas Rocha ce qui est censé simplifier le processus de décoration de l'objet. Je n'ai pas essayé cependant.

Parmi ses fonctionnalités sont:

  • Une collection de décorations d'articles en stock comprenant:
  • Espacement des éléments Diviseurs horizontaux / verticaux.
  • Élément de liste

929
2017-11-20 10:28



Ajoutez simplement

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

Aussi, vous devrez peut-être ajouter la dépendance
compile 'com.android.support:recyclerview-v7:27.1.0'

MODIFIER: 

Pour le personnaliser un peu, vous pouvez ajouter un dessin personnalisable:

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

Vous êtes libre d'utiliser tout dessin personnalisable, par exemple:

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

242
2017-12-17 18:40



Pourrais-je attirer votre attention sur ce dossier particulier sur Github par Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

C'est le fichier d'exemple DividerItemDecoration.java "tiré directement des démos de support".https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS)

J'ai été en mesure d'obtenir des lignes de séparation joliment après l'importation de ce fichier dans mon projet et l'ajouter comme un élément de décoration à la vue recycleur.

Voici à quoi ressemble mon onCreateView dans mon fragment contenant le 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;
}

Je suis sûr que le style supplémentaire peut être fait, mais c'est un point de départ. :)


237
2017-07-21 18:29



Simple ItemDecoration implémentation pour des espaces égaux entre tous les éléments.

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

128
2017-12-27 03:08



Le simple est de définir la couleur de fond pour RecyclerView et la couleur de fond différente pour les articles. Voici un exemple ...

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

et le Affichage item (Ca peut être n'importe quoi) avec la marge du bas "x" dp ou px.

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

Le résultat ...

enter image description here


91
2017-07-05 03:59



Je pense que l'utilisation d'un simple diviseur vous aidera

Pour ajouter un diviseur à chaque élément:
1- Ajouter ceci au répertoire 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:width="1dp"
    android:height="1dp" />
<solid android:color="#999999" />
</shape>

2- Créer une classe SimpleDividerItemDecoration
J'ai utilisé cet exemple pour définir cette 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- En activité ou en fragment, en utilisant RecyclerView, dans onCreateView, ajoutez ceci:

@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- Pour ajouter un espacement entre les éléments
vous avez juste besoin d'ajouter une propriété de remplissage à votre vue de l'article

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

37
2018-04-04 13:12



Comme je l'ai défini ItemAnimators. le ItemDecorator N'entrez pas et ne sortez pas avec l'animation.

J'ai simplement fini par avoir une ligne de vue dans mon fichier de disposition de chaque article. Cela a résolu mon cas. DividerItemDecoration senti être à beaucoup de sorcellerie pour un simple diviseur. Ou je pourrais manquer son utilisation réelle.

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

25
2018-03-16 04:35



Puisqu'il n'y a pas de bonne façon de mettre en œuvre ceci correctement en utilisant Material Design, j'ai juste fait l'astuce suivante pour ajouter un diviseur sur l'élément de la liste directement:

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

21
2018-04-13 18:22