RecyclerView'da öğeler arasına bölücüler ve boşluklar nasıl eklenir?


938

Bu, daha önce ListViewsınıfta divider ve dividerHeight parametrelerini kullanarak nasıl yapılabileceğinin bir örneğidir :

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

Ancak, RecyclerViewsınıfta böyle bir olasılık görmüyorum .

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

Bu durumda, kenar boşluklarını tanımlamak ve / veya doğrudan bir liste öğesinin düzenine özel bir bölücü görünümü eklemek uygun mu yoksa hedefime ulaşmanın daha iyi bir yolu var mı?



@EyesClear <TextView /> öğelerini başka bir xml ekleyin ve Aynı Etkinlik listesinde kullanın.
Amitsharma

7
Destek com.homeretailgroup.argos.android.view.decorators.DividerItemDecorationmRecyclerView.addItemDecoration(new DividerItemDecoration(activity, LinearLayoutManager.VERTICAL));
lib'de

Dikey listeler için liste öğenize alt kenar boşluğu ekleyebilirsiniz ve bölücü olarak kullanılabilir mi?
resw67

En basit yol, adaptör satırındaki ilk öğenin etrafına üst / alt kenar boşlukları eklemektir. android: layout_marginBottom = "4DP". (Üst düzene kenar boşlukları eklemeyi unutmayın).
pstorli

Yanıtlar:


1227

Ekim 2016 Güncellemesi

Android Destek Kitaplığı'nın 25.0.0 sürümü DividerItemDecorationsınıfı tanıttı :

DividerItemDecoration, a öğelerinin arasında bölücü olarak kullanılabilen bir RecyclerView.ItemDecoration öğesidir LinearLayoutManager. Hem destekler HORIZONTALve VERTICALyönelimleri.

Kullanımı:

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

Önceki cevap

Bazı cevaplar ya o zamandan beri kullanımdan kaldırılmış yöntemleri kullanın, ya da tam bir çözüm vermeyin, bu yüzden kısa, güncel bir sargı yapmaya çalıştım.


Sınıfın aksine ListView, RecyclerViewbölücüyle ilgili parametre yoktur. Bunun yerine, ItemDecorationbir RecyclerViewiç sınıfı genişletmeniz gerekir :

A ItemDecoration, uygulamanın, bağdaştırıcının veri kümesinden belirli öğe görünümlerine özel bir çizim ve düzen ofseti eklemesine izin verir. Bu, öğeler, vurgular, görsel gruplama sınırları ve daha fazlası arasında ayırıcılar çizmek için yararlı olabilir.

Hepsi ItemDecorations(öğe görünümleri önce, eklendikleri sırayla çizilir onDraw()() ve öğeleri sonra onDrawOver (içinde Canvas, RecyclerView, RecyclerView.State).

Vertical aralık ItemDecoration

Genişletin ItemDecoration, heightparametre olarak yer kaplayan özel yapıcı ekleyin ve getItemOffsets()yöntemi geçersiz kılın :

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

Son öğenin altına boşluk eklemek istemiyorsanız, aşağıdaki koşulu ekleyin:

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

Not: Ayrıca değiştirebilir outRect.top, outRect.leftve outRect.rightistenilen etki için özellikleri.

bölen ItemDecoration

Genişletme ItemDecorationve geçersiz kılma onDraw()yöntemi:

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

Varsayılan Android bölücü niteliklerini kullanan ilk yapıcıyı veya kendi çekilebilirinizi kullanan ikinci yapıcıyı çağırabilirsiniz, örneğin 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>

Not: bölücünün öğelerinizin üzerine çizilmesini istiyorsanız, onDrawOver()bunun yerine yöntemi geçersiz kılın .

kullanım

Yeni sınıf eklenti kullanmak için VerticalSpaceItemDecorationya DividerSpaceItemDecorationhiç RecyclerViewsenin veridiliminin örneğin, onCreateView()yöntemin:

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

Ayrıca eşya dekorasyon sürecini basitleştirmesi gereken Lucas Rocha'nın kütüphanesi de var. Yine de denemedim.

Onun arasında özellikleri şunlardır:

  • Aşağıdakiler de dahil olmak üzere stok öğesi süslemelerinden oluşan bir koleksiyon:
  • Öğe aralığı Yatay / dikey bölücüler.
  • Liste öğesi

3
@droppin_science Yanılıyorsam düzelt, ama içinde herhangi bir nesne yaratmıyorum onDraw(). Sadece var olan örneklere başvuruyorum.
EyesClear

1
Acaba bir Drawable oluşturmak yerine Paint kullanmak iyi bir fikir olup olmadığını merak ediyorum? Sonra çağırabilir canvas.drawLine(startX, startY, stopX, stopY, mPaint)içinde onDrawOver? Performans farkı var mı?
Arst

1
Sadece bilgilendirici bir yorum: listenizde daha sonra öğe eklemeyi planlıyorsanız, her zaman son öğeye boşluk ekleyin. Bunu yapmazsanız, bir öğe eklerken, alana sahip olmaz. VerticalSpace için teşekkürler!
Tsuharesu

24
Öğeler tamamen opaksa, yukarıda gösterildiği gibi DividerItemDecoration çalışmaz, bölücüler öğeler tarafından abartılır. Bu durumda, getItemOffsets () öğesini de geçersiz kılmanız ve ayırıcı öğenin dışına çıkması için outRect öğesine alt ofset eklemeniz gerekir. Alternatif olarak, bölücü afeteri öğeyi çizmek için onDraw () yerine onDrawOver () öğesini geçersiz kılabilirsiniz.
jpop

115
RecyclerView sadece bölücü eklemek için bir kod sayfası en iyi cevaptır. Yazıklar olsun, google.
07:16

480

Sadece ekle

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

Ayrıca bağımlılığı eklemeniz gerekebilir
compile 'com.android.support:recyclerview-v7:27.1.0'

DÜZENLE:

Biraz özelleştirmek için özel bir çekilebilir ekleyebilirsiniz:

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

Herhangi bir özel çekmeceyi kullanabilirsiniz, örneğin:

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

Etkinlik gerekmez. Bağlam yeterlidir
mac229

Bu doğru cevap olmalı. Plz, getActivity'yi değiştirin.
Jhon Fredy Trujillo Ortega

Ayrıca LayoutManager'ınızdan yönlendirme almak daha iyidir.
lsrom

Teşekkür ederim! Ayrıca Configurationdikey bölücü için de kullanabilirsiniz :if (orientation == Configuration.ORIENTATION_LANDSCAPE) { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL)); } else { recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));}
AlexS

3
Güzel cevap, ama son öğeden sonra da bir bölücü ekliyor.
CoolMind

256

Dikkatinizi Alex Fu'nun Github'daki bu dosyaya yönlendirebilir miyim: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

"Doğrudan destek demolarından alınan" DividerItemDecoration.java örnek dosyasıdır. ( Https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

Projemde bu dosyayı içe aktardıktan ve geri dönüşümcü görünümüne bir öğe dekorasyon olarak ekledikten sonra güzel bir bölücü çizgileri elde edebildim.

Recyclerview içeren parçamda onCreateView'ım şöyle görünüyor:

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

Eminim ek stil yapılabilir ancak bu bir başlangıç ​​noktasıdır. :)


Bunların yerini nasıl eklersiniz: "footerDividersEnabled", "headerDividersEnabled", "listSelector", "fastScrollEnabled", "smoothScrollbar", "textFilterEnabled"?
android geliştirici

Styling nasıl eklenir?
nizam.sp

Bu çözümü şekillendirmek için temanızdaki "android: listDivider" özelliğini geçersiz kılmanız gerekir
Pavel Dudka

1
Divider, RecyclerView ile çalışmaz. RecyclerView.itemDecoration kullanmanız gerekir. Bu yanıta bakın: stackoverflow.com/a/27664023/2311451
Cocorico

3
bölücü neden öğenin tüm genişliğini genişletiyor? nasıl gözlük gibi gösterilecek google.com/design/spec/components/lists.html#lists-specs
çip

156

ItemDecorationTüm öğeler arasında eşit boşluklar için basit uygulama.

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

yer alıyorum ama nasıl bir bölücü alabilirim
Pankaj Nimgade

26
getChildPositionartık kullanımdan kaldırıldı, getChildAdapterPositionbunun yerine kullanılabilir.
EyesClear

4
Çağrıyı kaldırmayı (yaptığım gibi) unutmayın super.getItemOffsets, yoksa ofsetlerinizin üzerine yazılacaktır.
jayeffkay

@EyesClear getChildLayoutPositionkullanılmamalıdır?
Avinash R

3
bu piksel cinsinden aralığı uygular mı?
filthy_wizard

108

Basit olanı RecyclerView için arka plan rengini ve öğeler için farklı arka plan rengini ayarlamaktır . İşte bir örnek ...

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

ve alt kenar boşluğu "x" dp veya px olan TextView öğesi (Yine de her şey olabilir).

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

Çıktı ...

resim açıklamasını buraya girin


2
Ne hile ama! yükleme sırasında yalnızca listeyi beyaz tutmanız gerekir.
Hamzeh Soboh

36
Aşırı çekilmeye dikkat edin!
shem

@shem ayrıntıya girebilir misiniz?
RominaV

7
Android'de katmanların üst üste birkaçını (etkinlik arka planı, geri dönüşüm görünümü arka planı ve öğe görünümü arka planı) çizerken - Android hepsini çiziyor, ayrıca kullanıcılar tarafından görülemeyenleri. Buna fazla para çekme denir ve performansınızı etkileyebilir, bununla ilgili daha fazla bilgiyi burada bulabilirsiniz: youtube.com/watch?v=T52v50r-JfE
shem

41

Basit bölücü kullanarak size yardımcı olacağını düşünüyorum

Her öğeye bölücü eklemek için:
1- Bunu çekilebilir dizine ekleyin 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 sınıfı oluştur
Bu sınıfı tanımlamak için bu örneği kullandım:
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 kullanan aktivite veya fragmanda, onCreateView içinde bunu ekleyin:

@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- Öğeler arasına boşluk
eklemek için öğe görünümünüze dolgu özelliği eklemeniz yeterlidir

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

Hücreler arasında da dikey bölücüler göstermesi için GridLayoutManager için nasıl çalışabilirim?
android geliştirici

2
resources.getDrawable () artık kullanımdan kaldırıldı. Bağlamda geçebilir ve ContextCompat.getDrawable (context, R.drawable.line_divider) kullanabilirsiniz
Eric B.

36

Ayarladığım gibi ItemAnimators. ItemDecoratorGirebilir veya animasyon ile birlikte çıkmak gerekmez.

Her öğenin öğe görünümü mizanpaj dosyamda bir görünüm çizgisine sahip oldum. Davamı çözdü. DividerItemDecorationbasit bir bölücü için çok fazla sihir olduğunu hissettim.

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

Haklısın. Animasyonlar ItemDecoration ile çalışmaz. Neden olduğundan emin değilim, ama bir şey belirtmeden animasyonlar alıyorum ve ItemDecoration tarafından oluşturulan çizgilerin takip etmesini çok dikkat dağıtıcı ve çirkin buluyorum. Sizinki gibi bir çözüm kullanacağım.
Michel

Son eşyayla nasıl başa çıktınız?
oldergod

@oldergod. Doğru ağrı noktasına işaret ettin. İlk önce bir tasarımın son öğe üzerinde bölücü olmasını kabul ediyorum. Ama bunu istemiyorsan. bu görünüme bir kimlik atayın ve konum son ise bindView'da gizleyin.
Javanator

@Javanator Tamam görüyorum, aynı yaklaşım benim. Teşekkürler.
oldergod

en basit en iyisidir
hyyou2010

27

Bu basit, bu kadar karmaşık bir koda ihtiyacınız yok

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

Bunu çekmecenize ekleyin: 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

Materyal Tasarımı kullanarak bunu doğru bir şekilde uygulamanın doğru bir yolu olmadığından, doğrudan liste öğesine bir bölücü eklemek için aşağıdaki hileyi yaptım:

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

Malzeme tasarımında bazı yükseklik bilgileri edindikten sonra DividerItemDecoration çalışmayı durdurdu (Inbox'taki gibi aynı etkiyi elde etmek için); basit bir şey için çok karmaşık hale geldi. Bu çözüm basit ve işe yarıyor.
DenisGL

21

Bölücü görünümünü ve ayrıca Bölücü Eklerini işleme biçimim bir RecyclerView uzantısı eklemektir.

1.

Görünüm veya RecyclerView adını vererek yeni bir uzantı dosyası ekleyin:

RecyclerViewExtension.kt

ve setDividerRecyclerViewExtension.kt dosyasının içine uzantı yöntemini ekleyin .

/*
* 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.

drawablePaketin içinde aşağıdaki gibi bir Çekilebilir kaynak dosyası oluşturun 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>

nereye sol ve sağ belirtebilirsiniz marjı üzerinde android:insetLeftve android:insetRight.

3.

RecyclerView öğesinin başlatıldığı Etkinliğinizde veya Parçanızda, aşağıdakileri arayarak özel çekilebilir öğeyi ayarlayabilirsiniz:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

Şerefe 🍺

Bölücü ile RecyclerView satır.


16

Birisi yalnızca öğeler arasına 10dp aralık eklemek istiyorsa, bunu aşağıdakilere çekilebilir bir ayar yaparak yapabilirsiniz DividerItemDecoration:

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

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

divider_10dpAşağıdakileri içeren çekilebilir bir kaynak nerede :

<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

Sadece daha büyük bir dolgu verdiğim ilk ve son öğeler hariç, tüm öğeler arasında eşit boşluklar elde ettiğim yaklaşımımı görmek için sadece öğeler arasındaki boşlukları arayanlar için RecyclerView. Dolguyu yalnızca yatay olarak sola / sağa LayoutManagerve dikeyde üst / alta uygularım 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

Görüşünüze bir kenar boşluğu ekleyin, benim için çalıştı.

android:layout_marginTop="10dp"

Sadece eklemek istiyorsanız eşit aralık ve bunu yapmak istiyorum XML , sadece set paddingsizin için RecyclerViewve eşit miktarda layoutMarginöğesine aşağıdaki konularda içine şişirmek RecyclerViewve arka plan rengi aralık rengini belirleyelim.


3
Bu işe yarayacak olsa da, bu doğru cevap değildir, çünkü bu, satır düzenine fazladan şeyler yapmadan sorunu çözmez, ayrıca üstte x1 kenar boşluğu görünür, satır 2 kenar boşluğu arasında görünecektir.
Sreekanth Karumanaghat

Bu iyi bir fikir değildir, çünkü overscrolllistenin sonunda çekerken oluşan efekt, dolgu uygulandığında gereksiz bir dolguya sahip olacaktırRecyclerView
AeroEchelon

Yükseklik / gölge, <?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>
vb.Gibi

11
  • İşte bölücü eklemek için basit bir kesmek
  • Geri dönüşümcünün öğesinin düzenine aşağıdaki gibi bir arka plan eklemeniz yeterlidir

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

Çekilebilir klasörde aşağıdaki shape_border.xml dosyasını oluşturun

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

İşte nihai sonuç - bölücü ile bir RecyclerView.

İşte nihai sonuç - bölücü ile bir RecyclerView.


1
Bu tercih edilen bir yaklaşım değildir. @EyesClear cevap başlatır onDraw'da INT ve rağmen parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1muhtemelen olmalıdır parent.getChildAdapterPosition(view) > 0birlikte outRect.bottom = mVerticalSpaceHeightolma outRect.top = mVerticalSpaceHeighto kabul cevap olmalıdır.
droppin_science

@droppin_science - Sadece bunun tercih edilen bir yaklaşım olmadığını söyleyerek ihmal edemezsiniz, bana beklendiği gibi doğru sonuçlar veriyor, ayrıca EyesClear'ın cevabına da bakıyorum, ancak bu cevap basit bir bölücü için çok karmaşık, ancak gerekiyorsa öğe ile bazı ekstra dekorasyon yapmak o zaman bu kabul edilebilir cevap olabilir.
turbandroid

Aşağı seçmenler için, bu cevap DividerItemDecoration için resmi sınıfların olmadığı bir zamanda verildi, bu yüzden bu cevap ile Leo Droidcoder tarafından verilen cevap arasındaki zaman boşluğunu karşılaştırın. :)
turbandroid

9

Eski bir gistten DividerItemDecoration'ı çatalladım ve kullanım durumuma uyacak şekilde basitleştirdim ve ayrıca son liste öğesinden sonra bir bölücü de dahil olmak üzere bölücüleri ListView'da çizildikleri şekilde çizmek için değiştirdim. Bu ayrıca dikey ItemAnimator animasyonlarını da ele alacaktır:

1) Bu sınıfı projenize ekleyin:

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) Dekoratörü RecylerView cihazınıza ekleyin:

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

Doğru, bir LinearLayoutManager içindir. Bir GridLayoutManager için uyarlamak için arkasındaki fikri alabilirsin.
OpenGL ES

8

Yerine oluşturmak shape xmliçin bölücü yüksekliğini ve rengini değiştirin. Programlı olarak

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)

bu yararlı bir cevaptır
taha

7

Bir Google aramasından alınan bu ItemDecoration'ı şu adrese ekleyin 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.");
    }
}
}

Bu yalnızca LinearLayoutManager için iyi çalışır. GridLayoutManager için ne yapılmalı?
android geliştirici

6

Bu bağlantı benim için bir cazibe gibi çalıştı:

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

Sonra faaliyetinizde:

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

Veya bir parça kullanıyorsanız:

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

1
Bu iyi çalışıyor, ancak listedeki son öğenin altındaki ayırıcıyı göstermiyor. Ben böyle gerekir: mShowFirstDivider = false, mShowLastDivider = trueancak çalışmaz. Neden olduğu hakkında bir fikrin var mı?
11'de gece sabitlendi

Bu, GridLayoutManager'ı iyi işleyemez.
android geliştirici

6

Öğeleri, geri dönüşüm görünümüne bağlı DividerItemDecoration gibi çeşitli dekoratörler kullanarak dekore edebiliriz:

Aşağıdakileri kullanmanız yeterlidir ... EyesClear tarafından verilen yanıttan alınmıştır

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

} ve ardından yukarıdakileri aşağıdaki gibi kullanın

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

Bu, aşağıda gösterildiği gibi listedeki her bir öğe arasındaki ayırıcıları görüntüler:

resim açıklamasını buraya girin

Ve daha fazla ayrıntı arayanlar için bu kılavuza göz atabilirsiniz RecyclerView _ CodePath Android Cliffnotlarını Kullanma

Buradaki bazı cevaplar kenar boşluklarının kullanılmasını önerir, ancak yakalama şudur: Hem üst hem de alt kenar boşluklarını eklerseniz, ikisi de öğeler arasında eklenmiş olarak görünür ve çok büyük olacaktır. Yalnızca ikisini de eklerseniz, tüm listenin üstünde veya altında kenar boşluğu kalmaz. Mesafenin yarısını üstten, yarısını altına eklerseniz, dış kenar boşlukları çok küçük olacaktır.

Bu nedenle, estetik açıdan doğru olan tek çözüm, sistemin doğru şekilde nereye uygulanacağını bildiği ayırıcıdır: öğeler arasında, ancak öğelerin üstünde veya altında değil.

Lütfen aşağıdaki yorumlarda herhangi bir şüpheniz varsa bana bildirin :)


1
Bu, DividerItemDecorationkodun neye benzediğini göstermez.
IgorGanapolsky

1
Onun bir AOSP sınıfı, sizin için kodu kazdık ..... gist.githubusercontent.com/alexfu/0f464fc3742f134ccd1e/raw/…
Anudeep Samaiya

İyi çalışmıyor: Farklı yükseklikteki satırları işlemez ve ızgaralar için dikey bir ayırıcı göstermez
android geliştirici

5

Çok Geç ama GridLayoutManagerben bunu kullanıyorum:

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

Bu çalışma, sahip olduğunuz herhangi bir açıklık sayısı için.

Ollie.


Üst alan hakkında, bunu destekleyecek şekilde nasıl değiştirirdiniz FlexboxLayoutManager?
android geliştirici

5

Programlı olarak kolayca ekleyebilirsiniz.

Layout Manager'ınız Linearlayout ise şunları kullanabilirsiniz:

DividerItemDecoration, bir LinearLayoutManager öğelerinin ayırıcısı olarak kullanılabilen bir RecyclerView.ItemDecoration yöntemidir. Hem YATAY hem de DİKEY yönelimleri destekler.

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

kaynak


5

XML kullanmayan basit, kod tabanlı bir cevaba ihtiyaç var gibi hissediyorum

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

Öğeler için aynı alan eklemek istiyorsanız, en basit yol, RecycleView için üst + sol dolgu ve kart öğelerine sağ + alt kenar boşlukları eklemektir.

dimens.xml

<resources>
    <dimen name="divider">1dp</dimen>
</resources>

list_item.xml

<CardView
 android:layout_marginBottom="@dimen/divider"
 android:layout_marginRight="@dimen/divider">
 ...
</CardView>

list.xml

<RecyclerView
 android:paddingLeft="@dimen/divider"
 android:paddingTop="@dimen/divider"
/>

4

Liste öğesine aşağıdaki gibi bir satır ekledim

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

1px ince çizgiyi çizecektir.

Son satır için ayırıcıyı gizlemek istiyorsanız divider.setVisiblity(View.GONE);, son liste Öğesi için onBindViewHolder'da.


1
Bunu tercih ediyorum, diğerleri çok karmaşık.
Sam Chen

3

' RecyclerViewDen biraz farklı ListView. Aslında, içinde benzer bir yapıya RecyclerViewihtiyaç ListViewvar. Örneğin, a LinearLayout. LinearLayoutHer öğeyi bölünmesi için parametreleri vardır. Aşağıdaki kodda ben öğeler arasında bir boşluk koyacak bir "dolgu" ile nesneler RecyclerViewoluşur . O alanı gerçekten küçük yapın ve bir çizgi elde edin.CardViewLinearLayout

İşte recyclerview_layout.xml'deki Recycler görünümü

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

Ve işte her bir öğe neye benziyor (ve android nedeniyle bölünmüş olarak gösteriliyor: her şeyi çevreleyen LinearLayout'ta dolgu.) Başka bir dosyada: cards_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    **android:padding="@dimen/activity_vertical_margin"**>
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:elevation="30dp"
        card_view:cardElevation="3dp">
            <TextView
                android:id="@+id/info_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
    </android.support.v7.widget.CardView>
</LinearLayout>

3

Gerçekten kolay bir çözüm RecyclerView-FlexibleDivider kullanmaktır

Bağımlılık ekle:

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

Geri dönüşüm görünümünüze ekleyin:

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

Ve işiniz bitti!


cazibe gibi çalışır ... açık kaynak paylaşımını sevmeliyim.
Billy

3

1.One of the Way birlikte cardview ve geri dönüşüm görünümü kullanarak bölücü gibi etkisi kolayca ekleyebilirsiniz. ex. https://developer.android.com/training/material/lists-cards.html

2. ve diğeri, geri dönüşüm görünümünün list_item_layout'una bölücü olarak görünüm eklemektir .

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

3
public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {

        private int mSpace = 0;
        private boolean mVerticalOrientation = true;

    public CommonItemSpaceDecoration(int space) {
        this.mSpace = space;
    }

    public CommonItemSpaceDecoration(int space, boolean verticalOrientation) {
        this.mSpace = space;
        this.mVerticalOrientation = verticalOrientation;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.top = SizeUtils.dp2px(view.getContext(), mSpace);
        if (mVerticalOrientation) {
            if (parent.getChildAdapterPosition(view) == 0) {
                outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace));
            } else {
                outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace));
            }
        } else {
            if (parent.getChildAdapterPosition(view) == 0) {
                outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0);
            } else {
                outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0);
            }
        }
    }
}

Bu, her öğenin üst ve alt kısmına (veya sol ve sağa) alan ekleyecektir 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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.