Bagaimana cara menambahkan pembagi dan spasi antara item di RecyclerView?

938

Ini adalah contoh bagaimana itu bisa dilakukan sebelumnya di ListViewkelas, menggunakan parameter divider dan 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"/>

Namun, saya tidak melihat kemungkinan seperti itu di RecyclerViewkelas.

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

Dalam hal itu, apakah boleh mendefinisikan margin dan / atau menambahkan tampilan pembagi kustom langsung ke tata letak item daftar atau apakah ada cara yang lebih baik untuk mencapai tujuan saya?

EyesClear
sumber
Ini membantu saya: stackoverflow.com/questions/26892296/…
Jared Burrows
@EyesClear Tambahkan item <TextView /> xml lain dan gunakan dalam daftar Aktivitas yang Sama.
Amitsharma
7
Ada kelas di lib dukungan com.homeretailgroup.argos.android.view.decorators.DividerItemDecorationdan menggunakannya seperti itu:mRecyclerView.addItemDecoration(new DividerItemDecoration(activity, LinearLayoutManager.VERTICAL));
fada21
Anda dapat menambahkan margin bawah ke item daftar Anda untuk daftar vertikal dan mungkin itu dapat digunakan sebagai pembagi?
resw67
Cara paling sederhana adalah dengan menambahkan margin atas / bawah di sekitar item pertama di baris adaptor. android: layout_marginBottom = "4dp". (Catatan menambahkan margin ke tata letak induk tidak akan memotongnya.)
pstorli

Jawaban:

1227

Pembaruan Oktober 2016

Versi 25.0.0 dari Perpustakaan Dukungan Android memperkenalkan DividerItemDecorationkelas:

DividerItemDecoration adalah RecyclerView.ItemDecoration yang dapat digunakan sebagai pembagi antara item a LinearLayoutManager. Ini mendukung keduanya HORIZONTALdan VERTICALorientasi.

Pemakaian:

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

Jawaban sebelumnya

Beberapa jawaban baik menggunakan metode yang sudah usang, atau tidak memberikan solusi lengkap, jadi saya mencoba untuk melakukan singkat, up-to-date.


Tidak seperti ListView, RecyclerViewkelas tidak memiliki parameter terkait pembagi. Sebaliknya, Anda perlu memperluas ItemDecoration, RecyclerViewkelas batin seorang:

An ItemDecorationmemungkinkan aplikasi untuk menambahkan offset gambar dan tata letak khusus ke tampilan item tertentu dari kumpulan data adaptor. Ini dapat berguna untuk menggambar pembagi antara item, sorotan, batas pengelompokan visual, dan lainnya.

Semua ItemDecorationsdiambil dalam urutan mereka ditambahkan, sebelum pandangan item (dalam onDraw()) dan setelah semuanya (di onDrawOver ( Canvas, RecyclerView, RecyclerView.State).

Vertical jarak ItemDecoration

Perpanjang ItemDecoration, tambahkan konstruktor khusus yang menggunakan spasi heightsebagai parameter dan getItemOffsets()metode override :

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

Jika Anda tidak ingin memasukkan ruang di bawah item terakhir, tambahkan kondisi berikut:

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

Catatan: Anda juga dapat memodifikasi outRect.top, outRect.leftdan outRect.rightproperti untuk efek yang diinginkan.

Pembagi ItemDecoration

Perluas ItemDecorationdan timpa onDraw()metode:

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

Anda dapat memanggil konstruktor pertama yang menggunakan atribut pembagi Android default, atau yang kedua yang menggunakan drawable Anda sendiri, misalnya 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>

Catatan: jika Anda ingin pembagi digambar di atas item Anda, onDrawOver()ganti metode.

Pemakaian

Untuk menggunakan kelas baru Anda tambahkan VerticalSpaceItemDecorationatau DividerSpaceItemDecorationke RecyclerView, misalnya dalam onCreateView()metode fragmen Anda :

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

Ada juga perpustakaan Lucas Rocha yang seharusnya menyederhanakan proses dekorasi item. Belum mencobanya.

Di antara fitur - fiturnya adalah:

  • Koleksi dekorasi stok barang termasuk:
  • Item spacing Pembagi horizontal / vertikal.
  • Daftar barang
EyesClear
sumber
3
@droppin_science Perbaiki saya jika saya salah, tapi saya tidak membuat objek apa pun di onDraw(). Saya hanya merujuk contoh yang sudah ada.
EyesClear
1
Saya bertanya-tanya apakah itu ide yang baik untuk menggunakan Paint daripada membuat drawable? Lalu aku bisa menelepon canvas.drawLine(startX, startY, stopX, stopY, mPaint)di onDrawOver? Adakah perbedaan kinerja?
Arst
1
Hanya komentar informatif: selalu tambahkan ruang ke item terakhir jika Anda berencana untuk menambahkan item nanti di daftar Anda. Jika Anda tidak melakukan itu, saat menambahkan item, itu tidak akan memiliki ruang. Terima kasih untuk VerticalSpace!
Tsuharesu
24
DividerItemDecoration seperti yang ditunjukkan di atas tidak akan berfungsi jika item sepenuhnya buram, pembagi akan ditarik oleh item. Dalam hal ini Anda perlu menimpa getItemOffsets () juga dan menambahkan offset bawah ke outRect sehingga pembagi berakhir di luar item. Atau, Anda bisa mengganti onDrawOver () dan bukannya onDraw () untuk menggambar pembagi setelah item.
jpop
115
Seluruh halaman kode untuk menambahkan pembagi ke recyclerView adalah jawaban terbaik. Malu pada Anda, google.
careful7j
480

Cukup tambahkan

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

Anda juga mungkin perlu menambahkan ketergantungan
compile 'com.android.support:recyclerview-v7:27.1.0'

EDIT:

Untuk sedikit mengubahnya, Anda dapat menambahkan drawable yang dapat disesuaikan:

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

Anda bebas menggunakan drawable kustom apa pun, misalnya:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@color/colorPrimary"/>
    <size android:height="0.5dp"/>
</shape>
Leo Droidcoder
sumber
Aktivitas tidak diperlukan. Konteks sudah cukup
mac229
Ini harus jawaban yang benar. Tolong, ubah getActivity menjadi konteks yang adil.
Jhon Fredy Trujillo Ortega
Juga lebih baik untuk mendapatkan orientasi dari LayoutManager Anda.
lsrom
Terima kasih! Anda juga dapat menggunakan Configurationpembagi vertikal:if (orientation == Configuration.ORIENTATION_LANDSCAPE) { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL)); } else { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));}
AlexS
3
Jawaban yang bagus, tetapi juga menambah pembagi setelah item terakhir.
CoolMind
256

Mungkin saya mengarahkan perhatian Anda ke file khusus ini di Github oleh Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

Ini contoh file DividerItemDecoration.java "ditarik langsung dari demo dukungan". ( Https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

Saya bisa mendapatkan garis pembagi dengan baik setelah mengimpor file ini di proyek saya dan menambahkannya sebagai hiasan item ke tampilan pendaur ulang.

Begini tampilan onCreateView saya di dalam fragmen yang berisi 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;
}

Saya yakin gaya tambahan dapat dilakukan, tetapi ini adalah titik awal. :)

Duy Nguyen
sumber
Bagaimana Anda menambahkan ganti yang: "footerDividersEnabled", "headerDividersEnabled", "listSelector", "fastScrollEnabled", "smoothScrollbar", "textFilterEnabled"?
pengembang android
Adakah masukan tentang Cara memasang Styling?
nizam.sp
untuk merancang solusi ini, Anda perlu mengganti atribut "android: listDivider" di tema Anda
Pavel Dudka
1
Divider tidak berfungsi dengan RecyclerView. Anda perlu menggunakan RecyclerView.itemDecoration. Lihat jawaban ini: stackoverflow.com/a/27664023/2311451
Cocorico
3
mengapa pembagi memperluas seluruh lebar item? cara menampilkan seperti di spesifikasi google.com/design/spec/components/lists.html#lists-specs
chip
156

ItemDecorationImplementasi sederhana untuk ruang yang sama antara semua item.

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;
        }
    }
}
SergeyA
sumber
saya mendapatkan ruang tetapi bagaimana cara mendapatkan pembagi
Pankaj Nimgade
26
getChildPositionsekarang sudah ditinggalkan, getChildAdapterPositionbisa digunakan sebagai gantinya.
EyesClear
4
Jangan lupa (seperti yang saya lakukan) untuk menghapus panggilan super.getItemOffsets, atau offset Anda akan ditimpa.
jayeffkay
@ EyesClear tidak seharusnya getChildLayoutPositiondigunakan?
Avinash R
3
apakah ini menerapkan spasi dalam piksel?
filthy_wizard
108

Yang sederhana adalah mengatur warna latar belakang untuk RecyclerView dan warna latar belakang yang berbeda untuk item. Berikut ini sebuah contoh ...

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

dan item TextView (bisa berupa apa saja) dengan margin bawah "x" dp atau px.

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

Hasil ...

masukkan deskripsi gambar di sini

Madan Sapkota
sumber
2
Trik apa! hanya perlu menjaga daftar putih saat memuat.
Hamzeh Soboh
36
Waspadalah terhadap penarikan berlebih!
Sem
@shem, bisakah Anda menguraikannya?
RominaV
7
Saat menggambar di Android beberapa layer satu di atas yang lain (latar belakang aktivitas, latar belakang tampilan daur ulang, dan latar belakang tampilan item) - Android menggambar semuanya, juga yang tidak terlihat oleh pengguna. Itu disebut overdraw dan mungkin memengaruhi kinerja Anda, lebih lanjut tentang hal ini di sini: youtube.com/watch?v=T52v50r-JfE
shem
41

Saya pikir menggunakan pembagi sederhana akan membantu Anda

Untuk menambahkan pembagi untuk setiap item:
1- Tambahkan ini ke direktori line_divider.xml yang dapat ditarik

<?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- Membuat kelas SimpleDividerItemDecoration
Saya menggunakan contoh ini untuk mendefinisikan kelas ini:
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- Dalam aktivitas atau fragmen yang menggunakan RecyclerView, di dalam onCreateView tambahkan ini:

@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- Untuk menambahkan jarak antar Item
Anda hanya perlu menambahkan properti padding ke tampilan item Anda

<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>
Belal mazlom
sumber
Bagaimana cara membuatnya berfungsi untuk GridLayoutManager, untuk menunjukkan pembagi vertikal antar sel juga?
pengembang android
2
resources.getDrawable () sekarang sudah tidak digunakan lagi. Anda dapat meneruskan dalam konteks dan menggunakan ContextCompat.getDrawable (konteks, R.drawable.line_divider)
Eric B.
36

Seperti yang telah saya atur ItemAnimators. ItuItemDecorator tidak masuk atau keluar bersama dengan animasi.

Saya akhirnya memiliki baris tampilan di file tata letak tampilan item saya masing-masing item. Ini menyelesaikan kasus saya. DividerItemDecorationmerasa terlalu banyak sihir untuk pembagi sederhana.

<View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:background="@color/lt_gray"/>
Javanator
sumber
Kamu benar. Animasi tidak berfungsi dengan ItemDecoration. Saya tidak yakin mengapa, tetapi tanpa saya menentukan apa-apa, saya mendapatkan animasi dan saya merasa sangat mengganggu dan jelek bahwa garis-garis yang dibuat oleh ItemDecoration tidak mengikuti. Jadi saya akan menggunakan solusi seperti milik Anda.
Michel
Bagaimana Anda menangani item terakhir?
oldergod
@oldergod. Anda menunjuk titik nyeri yang tepat. Saya pertama-tama akan setuju untuk desain memiliki pembagi pada item terakhir juga. Tetapi jika Anda tidak menginginkannya. tetapkan id untuk tampilan ini dan sembunyikan di bindView jika posisi terakhir.
Javanator
@Javanator Saya melihat ok, pendekatan yang sama yang saya ambil. Terima kasih.
oldergod
yang paling sederhana adalah yang terbaik
hyyou2010
27

Ini sederhana, Anda tidak perlu kode yang rumit

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

Tambahkan ini di drawable Anda: 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>
Faheem
sumber
21

Karena tidak ada cara yang tepat untuk mengimplementasikan ini dengan benar menggunakan Material Design, saya hanya melakukan trik berikut untuk menambahkan pembagi pada item daftar secara langsung:

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
Yoann Hercouet
sumber
DividerItemDecoration berhenti bekerja setelah saya memiliki beberapa informasi ketinggian desain material (untuk mendapatkan efek yang sama seperti di Kotak Masuk); terlalu rumit untuk hal sederhana. Solusi ini sederhana dan berhasil.
DenisGL
21

Cara saya menangani tampilan Divider dan Insets Divider adalah dengan menambahkan ekstensi RecyclerView.

1.

Tambahkan file ekstensi baru dengan memberi nama View atau RecyclerView:

RecyclerViewExtension.kt

dan tambahkan setDividermetode ekstensi di dalam 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.

Buat file sumber daya Drawable di dalam drawablepaket seperti 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>

di mana Anda dapat menentukan margin kiri dan kanan pada android:insetLeftdan android:insetRight.

3.

Pada Aktivitas atau Fragmen tempat RecyclerView diinisialisasi, Anda dapat mengatur kustom yang dapat digambar dengan menelepon:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

Ceria 🍺

Baris RecyclerView dengan pembagi.

Gent Berani
sumber
16

Jika ada yang mencari untuk hanya menambahkan, katakanlah, jarak 10dp antara item, Anda dapat melakukannya dengan mengatur drawable ke DividerItemDecoration:

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

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

Dimana divider_10dp sumber daya yang dapat digambar berisi:

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

Bagi mereka yang mencari hanya ruang antar item dalam RecyclerViewlihat pendekatan saya di mana Anda mendapatkan ruang yang sama antara semua item, kecuali dalam item pertama dan terakhir di mana saya memberikan bantalan yang lebih besar. Saya hanya menerapkan bantalan ke kiri / kanan secara horizontal LayoutManagerdan ke atas / bawah secara vertikal 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>
Ryan Amaral
sumber
11

Tambahkan margin ke tampilan Anda, itu berhasil untuk saya.

android:layout_marginTop="10dp"

Jika Anda hanya ingin menambahkan spasi yang sama dan ingin melakukannya dalam XML , tetapkan jumlah paddingAnda RecyclerViewdan jumlah yang sama layoutMarginuntuk item yang Anda kembangkan ke dalam RecyclerView, dan biarkan warna latar belakang menentukan warna spasi.

Materi Kuantum
sumber
3
Meskipun ini akan berhasil, ini bukan jawaban yang benar, misalnya, karena ini tidak menyelesaikan masalah tanpa melakukan hal-hal tambahan pada tata letak baris, juga, di bagian atas margin x1 akan muncul, antara baris margin x2 akan muncul.
Sreekanth Karumanaghat
Ini bukan ide yang baik karena overscrollefek ketika menarik di akhir daftar akan memiliki padding yang tidak perlu diterapkan ketika padding diterapkan keRecyclerView
AeroEchelon
Lebih baik untuk membungkus tata letak item dalam Support Library CardView sehingga Anda dapat mengontrol atribut lain misalnya ketinggian / bayangan, dll: <?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
  • Ini adalah hack sederhana untuk menambahkan pembagi
  • Cukup tambahkan latar belakang ke tata letak item pendaur ulang Anda sebagai berikut

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

Buat shape_border.xml berikut dalam folder yang dapat digambar

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

Ini adalah hasil akhir - sebuah RecyclerView dengan pembagi.

Ini adalah hasil akhir - sebuah RecyclerView dengan pembagi.

turbandroid
sumber
1
Ini bukan pendekatan yang disukai. Meskipun jawaban @EyesClear memulai int di onDraw dan parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1mungkin parent.getChildAdapterPosition(view) > 0dengan outRect.bottom = mVerticalSpaceHeightmenjadi outRect.top = mVerticalSpaceHeightitu harus menjadi jawaban yang diterima.
droppin_science
@droppin_science - Anda tidak dapat mengabaikannya dengan hanya mengatakan ini bukan pendekatan yang disukai, itu memberi saya hasil yang akurat seperti yang diharapkan, saya juga melihat jawaban EyesClear tetapi jawaban itu terlalu rumit untuk pembagi sederhana, namun jika perlu lakukan beberapa dekorasi tambahan dengan item maka itu bisa menjadi jawaban yang diterima.
turbandroid
Untuk pemilih bawah, jawaban ini diberikan pada saat tidak ada kelas resmi untuk DividerItemDecoration, jadi bandingkan saja jarak waktu antara jawaban ini dan jawaban berikut yang diberikan oleh Leo Droidcoder. :)
turbandroid
9

Saya bercabang DividerItemDecoration dari intis lama dan menyederhanakannya agar sesuai dengan kasus penggunaan saya, dan saya juga memodifikasinya untuk menggambar pembagi cara mereka digambar di ListView, termasuk pembagi setelah item daftar terakhir. Ini juga akan menangani animasi ItemAnimator vertikal:

1) Tambahkan kelas ini ke proyek Anda:

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) Tambahkan dekorator ke RecylerView Anda:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
Pelajari OpenGL ES
sumber
Benar, ini dimaksudkan untuk LinearLayoutManager. Anda dapat mengambil ide di baliknya untuk menyesuaikannya dengan GridLayoutManager.
Pelajari OpenGL ES
8

Alih-alih membuat shape xmluntuk mengubah tinggi dan warna pembagi. Anda dapat membuat seperti pemrograman

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)
Phan Van Linh
sumber
ini adalah jawaban yang berguna
taha
7

Diambil dari pencarian google, tambahkan ItemDecoration ini ke 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
sumber
Ini berfungsi baik hanya untuk LinearLayoutManager. Apa yang harus dilakukan untuk GridLayoutManager?
pengembang android
6

Tautan ini berfungsi seperti pesona bagi saya:

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

Kemudian dalam aktivitas Anda:

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

Atau ini jika Anda menggunakan sebuah fragmen:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(getActivity(), null));
Mikro
sumber
1
Ini berfungsi dengan baik, tetapi tidak menunjukkan pembagi di bawah item terakhir dalam daftar. Aku membutuhkannya seperti ini: mShowFirstDivider = false, mShowLastDivider = true, tapi itu tidak akan berhasil. Ada yang tahu kenapa?
nightfixed
Ini tidak bisa menangani GridLayoutManager dengan baik.
pengembang android
6

Kami dapat mendekorasi item menggunakan berbagai dekorator yang terpasang pada recyclerview seperti DividerItemDecoration:

Cukup gunakan berikut ini ... diambil dari jawaban oleh 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);
    }
}

} dan kemudian gunakan yang di atas sebagai berikut

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

Ini akan menampilkan pembagi antara setiap item dalam daftar seperti yang ditunjukkan di bawah ini:

masukkan deskripsi gambar di sini

Dan bagi mereka yang mencari rincian lebih lanjut dapat melihat panduan ini Menggunakan RecyclerView _ CodePath Android Cliffnotes

Beberapa jawaban di sini menyarankan penggunaan margin tetapi tangkapannya adalah: Jika Anda menambahkan margin atas dan bawah, keduanya akan muncul ditambahkan di antara item dan mereka akan terlalu besar. Jika Anda hanya menambahkan, maka tidak akan ada margin di bagian atas atau bawah dari seluruh daftar. Jika Anda menambahkan setengah jarak di bagian atas, setengah di bagian bawah, margin luar akan terlalu kecil.

Dengan demikian, satu-satunya solusi estetika yang benar adalah pembagi bahwa sistem tahu di mana harus diterapkan dengan benar: antara item tetapi tidak di atas atau di bawah item.

Tolong beri tahu saya jika ada keraguan dalam komentar di bawah ini :)

Anudeep Samaiya
sumber
1
Ini tidak menunjukkan DividerItemDecorationseperti apa kode itu.
IgorGanapolsky
1
Ini kelas AOSP, saya menggali kodenya untuk Anda ..... gist.githubusercontent.com/alexfu/0f464fc3742f134ccd1e/raw/…
Anudeep Samaiya
Ini tidak berfungsi dengan baik: Tidak menangani baris dengan ketinggian berbeda, dan tidak menunjukkan pembagi vertikal untuk kisi
pengembang android
5

Terlambat tetapi untuk GridLayoutManagersaya gunakan ini:

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

Ini berfungsi untuk semua rentang rentang yang Anda miliki.

Ollie.

Strevel Ollie
sumber
Tentang ruang atas, bagaimana Anda mengubahnya juga mendukung FlexboxLayoutManager?
pengembang android
5

Anda dapat menambahkan dengan mudah secara terprogram.

Jika Layout Manager Anda adalah Linearlayout maka Anda dapat menggunakan:

DividerItemDecoration adalah RecyclerView.ItemDecoration yang dapat digunakan sebagai pembagi antara item-item dari LinearLayoutManager. Ini mendukung orientasi HORIZONTAL dan VERTIKAL.

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

sumber

Beyaz
sumber
5

Saya merasa ada kebutuhan untuk jawaban sederhana berbasis kode yang tidak menggunakan 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);
Boober Bunz
sumber
4

Jika Anda ingin menambahkan ruang yang sama untuk item, cara paling sederhana adalah menambahkan padding atas + kiri untuk RecycleView dan margin kanan + bawah ke item kartu.

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

Saya telah menambahkan item baris dalam daftar seperti di bawah ini

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

1px akan menarik garis tipis.

Jika Anda ingin menyembunyikan pembagi untuk baris terakhir maka divider.setVisiblity(View.GONE);pada onBindViewHolder untuk Item daftar terakhir.

Raja Peela
sumber
1
Saya lebih suka yang ini, yang lain terlalu rumit.
Sam Chen
3

Ini RecyclerViewsedikit berbeda dari ListView. Sebenarnya, RecyclerViewkebutuhan ListViewstruktur seperti di dalamnya. Sebagai contoh, a LinearLayout. The LinearLayoutmemiliki parameter untuk membagi setiap elemen. Dalam kode di bawah ini saya memiliki objek yang RecyclerViewterdiri dari CardViewaLinearLayout dengan "bantalan" yang akan menempatkan beberapa ruang antara item. Buat ruang itu sangat kecil dan Anda mendapat garis.

Berikut tampilan Pendaur Ulang di 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>

Dan di sini terlihat seperti apa setiap item (dan terlihat terbagi karena android: padding di LinearLayout yang mengelilingi segalanya.) Di file lain: 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
sumber
3

Solusi yang sangat mudah adalah dengan menggunakan RecyclerView-FlexibleDivider

Tambahkan ketergantungan:

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

Tambahkan ke recyclerview Anda:

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

Dan kamu selesai!

Cristan
sumber
bekerja seperti pesona ... harus suka berbagi sumber terbuka.
Billy
3

1.One of the Way adalah dengan menggunakan tampilan cardview dan pendaur ulang bersama kita dapat dengan mudah menambahkan efek seperti pembagi. ex. https://developer.android.com/training/material/lists-cards.html

2.dan lainnya adalah dengan menambahkan view sebagai divider ke list_item_layout dari view recycler .

        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent" />
vicky
sumber
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);
            }
        }
    }
}

Ini akan menambah ruang di setiap bagian atas dan bawah (atau kiri dan kanan). Kemudian Anda dapat mengaturnya untuk Anda 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
sumber