Как добавить разделители и пробелы между элементами в RecyclerView?

938

Это пример того, как это можно было сделать ранее в ListViewклассе, используя параметры divider и 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"/>

Однако я не вижу такой возможности в 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"/>

В этом случае можно ли определять поля и / или добавлять пользовательский вид делителя непосредственно в макет элемента списка или есть лучший способ достичь моей цели?

EyesClear
источник
Это помогло мне: stackoverflow.com/questions/26892296/…
Джаред Барроуз
@EyesClear Добавьте элементы <TextView /> в другой xml и используйте его в списке Same Activity.
Амитшарма
7
Есть класс поддержки в lib com.homeretailgroup.argos.android.view.decorators.DividerItemDecorationи используйте его так:mRecyclerView.addItemDecoration(new DividerItemDecoration(activity, LinearLayoutManager.VERTICAL));
fada21
Вы можете добавить нижнее поле в свой элемент списка для вертикальных списков и, возможно, его можно использовать в качестве разделителя?
resw67
Самый простой способ - добавить верхние / нижние поля вокруг первого элемента в строке адаптера. андроид: layout_marginBottom = "4ДП". (Обратите внимание, что добавление полей в родительский макет не приведет к его сокращению.)
pstorli

Ответы:

1228

Обновление за октябрь 2016

В версии 25.0.0 библиотеки поддержки Android представлен DividerItemDecorationкласс:

DividerItemDecoration - это RecyclerView.ItemDecoration, который можно использовать в качестве разделителя между элементами объекта LinearLayoutManager. Он поддерживает как HORIZONTALи VERTICALориентации.

Применение:

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

Предыдущий ответ

В некоторых ответах либо используются методы, которые с тех пор устарели, либо они не дают полного решения, поэтому я попытался сделать короткую, актуальную сводку.


В отличие от этого ListView, RecyclerViewкласс не имеет параметров, связанных с делителем. Вместо этого вам необходимо расширить ItemDecoration, A RecyclerView«S внутренний класс:

ItemDecorationПозволяет приложению добавить специальный рисунок и расположение смещение конкретных представлений элементов из набора данных адаптера. Это может быть полезно для рисования разделителей между элементами, бликами, визуальными границами группировки и многим другим.

Все ItemDecorationsрисуются в порядке их добавления, до представления элементов (в onDraw()) и после пунктов (в onDrawOver ( Canvas, RecyclerView, RecyclerView.State).

Vertical расстояние ItemDecoration

Расширить ItemDecoration, добавить пользовательский конструктор, который принимает пространство heightв качестве параметра и переопределить getItemOffsets()метод:

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

Если вы не хотите вставлять пробел под последним элементом, добавьте следующее условие:

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

Примечание: Вы также можете изменить outRect.top, outRect.leftи outRect.rightсвойство для достижения желаемого эффекта.

делитель ItemDecoration

Расширить ItemDecorationи переопределить onDraw()метод:

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

Вы можете либо вызвать первый конструктор, который использует атрибуты делителя Android по умолчанию, либо второй, который использует ваш собственный drawable, например drawable /divr.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>

Примечание: если вы хотите, чтобы разделитель отображался поверх ваших элементов, используйте onDrawOver()метод переопределения .

Применение

Чтобы использовать ваш новый класс add VerticalSpaceItemDecorationили DividerSpaceItemDecorationto RecyclerView, например, в onCreateView()методе вашего фрагмента :

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

Также есть библиотека Лукаса Роча, которая должна упростить процесс украшения предметов. Хотя не пробовал.

Среди его особенностей :

  • Коллекция художественных оформлений, включающих в себя:
  • Расстояние между предметами Горизонтальные / вертикальные разделители.
  • Пункт списка
EyesClear
источник
3
@droppin_science Поправьте меня, если я ошибаюсь, но я не создаю никаких объектов в onDraw(). Я просто ссылаюсь на уже существующие экземпляры.
EyesClear
1
Интересно, будет ли хорошей идеей использовать Paint вместо создания рисования? Тогда я могу позвонить canvas.drawLine(startX, startY, stopX, stopY, mPaint)в onDrawOver? Есть разница в производительности?
Арст
1
Просто информативный комментарий: всегда добавляйте пробел к последнему элементу, если вы планируете добавить элементы позже в свой список. Если вы этого не сделаете, при добавлении элемента у него не будет места. Спасибо за VerticalSpace!
Цухаресу
24
DividerItemDecoration, как показано выше, не будет работать, если элементы полностью непрозрачны, разделители будут перезаписаны элементами. В этом случае вам также необходимо переопределить getItemOffsets () и добавить нижнее смещение в outRect, чтобы разделитель оказался вне элемента. В качестве альтернативы, вы можете переопределить onDrawOver () вместо onDraw (), чтобы нарисовать разделитель, влияющий на элемент.
Jpop
116
Целая страница кода, чтобы просто добавить разделитель к recyclerView - лучший ответ. Позор тебе, гугл.
заботливый7
480

Просто добавь

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

Также вам может понадобиться добавить зависимость
compile 'com.android.support:recyclerview-v7:27.1.0'

РЕДАКТИРОВАТЬ:

Чтобы немного его настроить, вы можете добавить собственный чертеж:

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

Вы можете использовать любой пользовательский объект, например:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@color/colorPrimary"/>
    <size android:height="0.5dp"/>
</shape>
Лев Droidcoder
источник
Активность не нужна. Достаточно контекста
mac229
Это должен быть правильный ответ. Plz, измените getActivity, чтобы просто контекст.
Джон Фреди Трухильо Ортега
Также лучше получить ориентацию от вашего LayoutManager.
lsrom
Спасибо! Также вы можете использовать Configurationдля вертикального делителя:if (orientation == Configuration.ORIENTATION_LANDSCAPE) { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL)); } else { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));}
AlexS
4
Хороший ответ, но он добавляет разделитель также после последнего элемента.
CoolMind
256

Могу я обратить ваше внимание на этот конкретный файл на Github Алекса Фу: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

Это файл примера DividerItemDecoration.java, "извлеченный прямо из демонстрационных роликов поддержки". ( Https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

После импорта этого файла в мой проект я смог получить разделительные линии и добавить его в качестве украшения элемента в представление переработчика.

Вот как выглядит мой onCreateView в моем фрагменте, содержащем 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;
}

Я уверен, что можно сделать дополнительный стиль, но это отправная точка. :)

Дуй Нгуен
источник
Как добавить вместо заменить те: «footerDividersEnabled», «headerDividersEnabled», «listSelector», «fastScrollEnabled», «smoothScrollbar», «textFilterEnabled»?
Android-разработчик
Любые входы на Как поставить Styling?
nizam.sp
Чтобы стилизовать это решение, вам нужно переопределить атрибут «android: listDivider» в вашей теме
Павел Дудка
1
Делитель не работает с RecyclerView. Вам необходимо использовать RecyclerView.itemDecoration. Смотрите этот ответ: stackoverflow.com/a/27664023/2311451
Cocorico
3
почему разделитель расширяет всю ширину элемента? как отобразить как в спецификации google.com/design/spec/components/lists.html#lists-specs
чип
156

Простая ItemDecorationреализация для равных мест между всеми элементами.

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;
        }
    }
}
Сергея
источник
я получаю место, но как мне получить делитель
Pankaj Nimgade
26
getChildPositionтеперь устарела, getChildAdapterPositionможет использоваться вместо
EyesClear
4
Не забудьте (как я) удалить вызов super.getItemOffsets, иначе ваши смещения будут перезаписаны.
Jayeffkay
@EyesClear не должен getChildLayoutPositionбыть использован?
Авинаш Р
3
это реализует интервал в пикселях?
filthy_wizard
108

Самый простой - установить цвет фона для RecyclerView и другой цвет фона для элементов. Вот пример ...

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

и элемент TextView (это может быть что угодно) с нижним полем «x» dp или px.

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

Выход ...

введите описание изображения здесь

Мадан Сапкота
источник
2
Какой трюк! нужно только сохранить список белым при загрузке.
Хамзех Собох
36
Остерегайтесь овердрайта!
Сим
@ Шем, не могли бы вы уточнить?
RominaV
7
При рисовании в Android нескольких слоев один над другим (фон активности, фон повторного просмотра и фон представления элементов) - Android рисует их все, а также те, которые не видны пользователям. Это называется overdraw и может повлиять на вашу производительность, подробнее об этом здесь: youtube.com/watch?v=T52v50r-JfE
shem
41

Я думаю, что использование простого разделителя поможет вам

добавить разделитель для каждого элемента:
1- Добавьте это в каталог 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. Создание класса SimpleDividerItemDecoration.
Я использовал этот пример для определения этого класса:
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- В упражнении или фрагменте, которые используют RecyclerView, внутри onCreateView добавьте это:

@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- Чтобы добавить интервал между Предметами,
вам просто нужно добавить свойство отступов к вашему виду.

<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>
Белал мазлом
источник
Как заставить это работать для GridLayoutManager, для показа вертикальных разделителей также между ячейками?
разработчик Android
2
resources.getDrawable () теперь устарела. Вы можете передать контекст и использовать ContextCompat.getDrawable (context, R.drawable.line_divider)
Эрик Б.
36

Как я и установил ItemAnimators. ItemDecoratorНе входить или выходить вместе с анимацией.

Я просто получил строку представления в файле макета представления каждого элемента. Это решило мой случай. DividerItemDecorationчувствовал себя слишком большим колдовством для простого делителя.

<View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:background="@color/lt_gray"/>
Javanator
источник
Вы правы. Анимации не работают с ItemDecoration. Я не уверен почему, но без указания чего-либо, я получаю анимацию, и я нахожу это очень отвлекающим и уродливым, что линии, созданные ItemDecoration, не следуют. Поэтому я буду использовать решение, подобное вашему.
Мишель
Как вы справились с последним пунктом?
старше
@oldergod. Вы указали на правую болевую точку. Сначала я согласился бы с дизайном, чтобы иметь разделитель и для последнего элемента. Но если ты этого не хочешь. назначьте идентификатор этому представлению и скройте в bindView, если позиция является последней.
Javanator
@Javanator Я вижу хорошо, тот же подход, который я выбрал. Спасибо.
старше
самый простой самый лучший
hyyou2010
27

Это просто, вам не нужен такой сложный код

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

Добавьте это в свой чертеж: 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

Поскольку пока нет правильного способа реализовать это с помощью Material Design, я просто выполнил следующий трюк, чтобы напрямую добавить разделитель в элемент списка:

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
Йоанн Херкуэ
источник
DividerItemDecoration перестает работать после того, как у меня есть некоторая информация о высоте дизайна материала (чтобы получить тот же эффект, что и в Inbox); это слишком сложно для простой вещи. Это решение простое и работает.
DenisGL
21

Способ работы с представлением «Разделитель», а также «Вставки разделителя» заключается в добавлении расширения RecyclerView.

1.

Добавьте новый файл расширения с именем View или RecyclerView:

RecyclerViewExtension.kt

и добавьте setDividerметод расширения в файл 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.

Создайте файл ресурсов Drawable внутри drawableпакета, например 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>

где вы можете указать левый и правый край на android:insetLeftи android:insetRight.

3.

В вашей Деятельности или Фрагменте, где инициализируется RecyclerView, вы можете установить настраиваемое рисование, вызвав:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

Приветствия 🍺

RecyclerView строка с разделителем.

Гент Берани
источник
16

Если кто-то хочет добавить, скажем, 10dp интервал между элементами, вы можете сделать это, установив drawable в DividerItemDecoration:

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

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

Где divider_10dpрисованный ресурс, содержащий:

<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

На самом деле это не решает проблему, но в качестве временного обходного пути вы можете установить свойство useCompatPadding на карточке в макете XML, чтобы оно измерялось так же, как и в версиях до Lollipop.

card_view:cardUseCompatPadding="true"
Кевин Грант
источник
11

Для тех , кто ищет только для пространств между элементами в RecyclerViewсм моего подход , при котором вы получаете равные промежутки между всеми деталями, за исключением первых и последних пунктами , где я дал большие отступы. Я применяю отступы только влево / вправо по горизонтали LayoutManagerи сверху / снизу по вертикали 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

Добавьте маржу к вашему мнению, это сработало для меня.

android:layout_marginTop="10dp"

Если вы просто хотите , чтобы добавить равное расстояние и хотите сделать это в XML , просто установить paddingна свой RecyclerViewи равное количество layoutMarginдля элемента , который вы раздувать в ваш RecyclerView, и пусть цвет фона определяют цвет интервала.

Квант Маттер
источник
3
Хотя это будет работать, это не правильный ответ, например, потому что это не решает проблему, не делая лишних вещей с расположением строк, также, в верхней части появится поле x1, между строками поле x2.
Sreekanth Karumanaghat
Это не очень хорошая идея, потому что к overscrollэффекту при перетаскивании в конце списка будет добавлен ненужный отступ, когда к нему применяется RecyclerView
отступ
Лучше обернуть макет элемента в CardView Support Library, чтобы вы могли контролировать другие атрибуты, например высоту / тень и т. Д .: <?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
  • Вот простой взломать, чтобы добавить разделитель
  • Просто добавьте фон к макету вашего предмета утилизации следующим образом

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

Создайте следующий shape_border.xml в папке drawable

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

Вот окончательный результат - RecyclerView с разделителем.

Вот окончательный результат - RecyclerView с разделителем.

turbandroid
источник
1
Это не предпочтительный подход. Хотя @EyesClear ответ инициированные Int находится в OnDraw и , parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1вероятно , следует parent.getChildAdapterPosition(view) > 0с outRect.bottom = mVerticalSpaceHeightстав outRect.top = mVerticalSpaceHeightдолжно быть приемлемым ответом.
droppin_science
@droppin_science - Вы не можете пренебрегать этим, просто сказав, что это не предпочтительный подход, он дает мне точные результаты, как и ожидалось, я также смотрю на ответ EyesClear, но этот ответ слишком сложен для простого делителя, однако, если есть необходимость Затем сделайте дополнительное украшение предметом, который может быть принятым ответом.
турбандроид
Для опущенных избирателей этот ответ был дан в то время, когда не было официальных классов для DividerItemDecoration, поэтому просто сравните временной промежуток между этим ответом и следующим ответом, данным Лео Дроидкодером. :)
турбандроид
9

Я раздвоил DividerItemDecoration из более ранней сущности и упростил его, чтобы он соответствовал моему сценарию использования, и я также изменил его, чтобы нарисовать разделители так, как они нарисованы в ListView, включая разделитель после последнего элемента списка. Это также будет обрабатывать вертикальную анимацию ItemAnimator:

1) Добавьте этот класс в ваш проект:

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) Добавьте декоратор в свой RecylerView:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
Изучите OpenGL ES
источник
Правильно, это предназначено для LinearLayoutManager. Вы можете воспользоваться этой идеей, чтобы адаптировать ее для GridLayoutManager.
Изучите OpenGL ES
8

Вместо того, чтобы создать shape xmlдля изменения высоты и цвета разделителя. Вы можете создать программно как

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)
Фан Ван Линь
источник
это полезный ответ
таха
7

Взятый из поиска Google, добавьте этот ItemDecoration к вашему 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.");
    }
}
}
gatlingxyz
источник
Это хорошо работает только для LinearLayoutManager. Что нужно сделать для GridLayoutManager?
разработчик Android
6

Эта ссылка для меня сработала:

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

Тогда в вашей деятельности:

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

Или это, если вы используете фрагмент:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(getActivity(), null));
Микро
источник
1
Это прекрасно работает, но не показывает разделитель под последним элементом в списке. Мне нужно это так mShowFirstDivider = false, mShowLastDivider = trueно это не сработает. Есть идеи почему?
исправлено
Это не может хорошо обрабатывать GridLayoutManager.
разработчик Android
6

Мы можем украсить элементы, используя различные декораторы, прикрепленные к представлению переработчика, такие как DividerItemDecoration:

Просто используйте следующее ... взято из ответа 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);
    }
}

}, а затем используйте вышеизложенное следующим образом

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

Это отобразит разделители между каждым элементом в списке, как показано ниже:

введите описание изображения здесь

А те, кто ищет подробности, могут ознакомиться с этим руководством. Использование RecyclerView _ CodePath Android Cliffnotes

Некоторые ответы здесь предполагают использование полей, но выгода заключается в следующем: если вы добавите верхние и нижние поля, они будут добавлены между элементами и будут слишком большими. Если вы добавите только один из них, не будет никакого поля ни в верхней, ни в нижней части всего списка. Если вы добавите половину расстояния сверху, половину снизу, то внешние поля будут слишком маленькими.

Таким образом, единственное эстетически правильное решение - это разделитель, который система знает, где правильно применять: между элементами, но не над или под элементами.

Пожалуйста, дайте мне знать о любых сомнениях в комментариях ниже :)

Анудип Самайя
источник
1
Это не демонстрация того, как DividerItemDecorationвыглядит код.
Игорь Ганапольский
1
Это класс AOSP, я выкопал код для вас ..... gist.githubusercontent.com/alexfu/0f464fc3742f134ccd1e/raw/…
Anudeep Samaiya
Он не работает хорошо: он не обрабатывает строки разной высоты и не показывает вертикальный разделитель для сеток
Android-разработчик
5

Слишком поздно, но GridLayoutManagerя использую это:

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

Эта работа для любого количества пролетов у вас есть.

Олли.

Олли Стревел
источник
О топ-пространстве, как бы вы изменили его, чтобы также поддерживать FlexboxLayoutManager?
Android-разработчик
5

Вы можете добавить с программно легко.

Если ваш Layout Manager - Linearlayout, вы можете использовать:

DividerItemDecoration - это RecyclerView.ItemDecoration, которое можно использовать в качестве разделителя между элементами LinearLayoutManager. Он поддерживает горизонтальную и вертикальную ориентацию.

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

источник

Beyaz
источник
5

Мне кажется, что нужен простой ответ на основе кода, который не использует 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

Если вы хотите добавить одинаковое пространство для элементов, самый простой способ - добавить верхнее + левое заполнение для RecycleView и правое + нижнее поле для элементов карточки.

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"
/>
limitium
источник
4

Я добавил строку в элемент списка, как показано ниже

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

1px нарисует тонкую линию.

Если вы хотите скрыть разделитель для последней строки, то divider.setVisiblity(View.GONE);в onBindViewHolder для последнего элемента списка.

Раджа Пила
источник
1
Я предпочитаю этот, другие слишком сложны.
Сэм Чен
3

Это RecyclerViewнемного отличается от ListView. На самом деле, RecyclerViewнужна ListViewподобная структура. Например, LinearLayout. LinearLayoutИмеет параметры для деления каждого элемента. В коде ниже я RecyclerViewсостою из CardViewобъектов в пределахLinearLayout с «отступом», который будет помещать некоторое пространство между элементами. Сделайте это пространство действительно маленьким, и вы получите линию.

Вот представление Recycler в 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>

И вот как выглядит каждый элемент (и он отображается как разделенный из-за андроида: отступ в LinearLayout, который окружает все.) В другом файле: 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>
fiacobelli
источник
3

Действительно простое решение - использовать RecyclerView-FlexibleDivider.

Добавить зависимость:

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

Добавьте в свой список переработчиков:

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

И вы сделали!

Cristan
источник
работает как шарм ... должен любить обмен с открытым исходным кодом.
Билли
3

1. Одним из путей является совместное использование карт и вида переработчика, мы можем легко добавить эффект, например, делитель. ех. https://developer.android.com/training/material/lists-cards.html

2. и другое, добавив представление в качестве разделителя к list_item_layout представления переработчика .

        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent" />
Vicky
источник
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);
            }
        }
    }
}

Это добавит пространство сверху и снизу каждого элемента (или слева и справа). Затем вы можете установить его на свой 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);
    }
}
wizChen
источник