Hoe kan een scheidingslijn worden toegevoegd in een Android RecyclerView?

Ik ontwikkel een Android-applicatie waarbij ik RecyclerViewgebruik. Ik moet een verdelertoevoegen in RecyclerView.
Ik heb geprobeerd toe te voegen –

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

hieronder staat mijn xml-code –

  <android.support.v7.widget.RecyclerView
    android:id="@+id/drawerList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="15dp"
    />

Antwoord 1, autoriteit 100%

In de update van oktober 2016 heeft de ondersteuningsbibliotheek v25.0.0 nu een standaardimplementatie van standaard horizontale en verticale scheidingslijnen!

https://developer.android.com/reference/ android/support/v7/widget/DividerItemDecoration.html

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

Antwoord 2, autoriteit 75%

De juiste manier is om ItemDecorationte definiëren voor de RecyclerViewis als volgt

SimpleDividerItemDecoration.java

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
    }
    @Override
    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);
        }
    }
}

Of als u kotlin gebruikt:
SimpleDividerItemDecoration.kt

class SimpleDividerItemDecoration(context: Context, @DrawableRes dividerRes: Int) : ItemDecoration() {
    private val mDivider: Drawable = ContextCompat.getDrawable(context, dividerRes)!!
    override fun onDrawOver(c: Canvas, parent: RecyclerView) {
        val left = parent.paddingLeft
        val right = parent.width - parent.paddingRight
        val childCount = parent.childCount
        for (i in 0 until childCount) {
            val child: View = parent.getChildAt(i)
            val params = child.layoutParams as RecyclerView.LayoutParams
            val top: Int = child.bottom + params.bottomMargin
            val bottom = top + mDivider.intrinsicHeight
            mDivider.setBounds(left, top, right, bottom)
            mDivider.draw(c)
        }
    }
}

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="@color/dark_gray" />
</shape>

Stel het uiteindelijk zo in

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));

Bewerken

Zoals aangegeven door @Alan Solitar

context.getResources().getDrawable(R.drawable.line_divider); 

wordt afgeschreven in plaats van wat u kunt gebruiken

ContextCompat.getDrawable(context,R.drawable.line_divider);

Antwoord 3, autoriteit 13%

Als u zowel horizontale als verticale scheidingslijnen wilt hebben:

  1. Definieer horizontaal & verticale scheidingslijnen:

    horizontal_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
      <size android:height="1dip" />
      <solid android:color="#22000000" />
    </shape>
    

    vertical_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <size android:width="1dip" />
        <solid android:color="#22000000" />
    </shape>
    
  2. Voeg dit codesegment hieronder toe:

    DividerItemDecoration verticalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.HORIZONTAL);
    Drawable verticalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.vertical_divider);
    verticalDecoration.setDrawable(verticalDivider);
    recyclerview.addItemDecoration(verticalDecoration);
    DividerItemDecoration horizontalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.VERTICAL);
    Drawable horizontalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.horizontal_divider);
    horizontalDecoration.setDrawable(horizontalDivider);
    recyclerview.addItemDecoration(horizontalDecoration);
    

Antwoord 4, autoriteit 13%

Al deze antwoorden brachten me dichtbij, maar ze misten elk een belangrijk detail. Na wat onderzoek vond ik de gemakkelijkste route om een ​​combinatie van deze 3 stappen te zijn:

  1. Gebruik DividerItemDecoration
  2. Maak een scheidingslijn met de juiste kleur
  3. Stel deze scheidingslijn in uw thema in als de listDivider

Stap 1: tijdens het configureren van RecyclerView

recyclerView.addItemDecoration(
        new DividerItemDecoration(context, layoutManager.getOrientation()));

Stap 2: in een bestand zoals res/drawable/divider_gray.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size android:width="1px" android:height="1px" />
    <solid android:color="@color/gray" />
</shape>

Stap 3: in het thema van de app

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Other theme items above -->
    <item name="android:listDivider">@drawable/divider_gray</item>
</style>

EDIT: Bijgewerkt om de laatste scheidingslijn over te slaan:
Nadat ik dit een beetje had gebruikt, realiseerde ik me dat het een scheidingslijn aan het tekenen was na het laatste item, wat vervelend was. Dus heb ik Stap 1als volgt aangepast om dat standaardgedrag in DividerItemDecoration te negeren (natuurlijk is het maken van een aparte klasse een andere optie):

recyclerView.addItemDecoration(
        new DividerItemDecoration(context, layoutManager.getOrientation()) {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                int position = parent.getChildAdapterPosition(view);
                // hide the divider for the last child
                if (position == parent.getAdapter().getItemCount() - 1) {
                    outRect.setEmpty();
                } else {
                    super.getItemOffsets(outRect, view, parent, state);
                }
            }
        }
);

Antwoord 5, autoriteit 3%

Maak een apart xml-bestand in de map res/drawable

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

Verbind dat xml-bestand (uw_bestand) aan de hoofdactiviteit, als volgt:

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

Antwoord 6, autoriteit 3%

Probeer deze eenvoudige code van één regel

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

Antwoord 7, autoriteit 2%

Ik denk dat je Fragmentsgebruikt om RecyclerView

te hebben

Voeg deze regels eenvoudig toe na het maken van uw RecyclerViewen LayoutManager-objecten

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

Dat is het!

Het ondersteunt zowel HORIZONTALE als VERTICALE oriëntaties.


Antwoord 8, autoriteit 2%

Je moet de volgende regel toevoegen…

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

Antwoord 9, autoriteit 2%

Dus dit is misschien niet de juiste manier, maar ik heb zojuist een weergave toegevoegd aan de weergave met één item van de RecyclerView (omdat ik denk dat er geen ingebouwde functie is), zoals:

<View
    android:layout_width="fill_parent"
    android:layout_height="@dimen/activity_divider_line_margin"
    android:layout_alignParentBottom="true"
    android:background="@color/tasklist_menu_dividerline_grey" />

Dit betekent dat elk item een ​​regel heeft die het onderaan vult. Ik maakte het ongeveer 1 dp hoog met een #111111achtergrond. Dit geeft het ook een soort “3D” effect.


Antwoord 10, autoriteit 2%

Je kunt een eenvoudige herbruikbare scheidingswand maken.

Scheiding maken:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }
    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = 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 dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();
            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}

Verdeellijn maken: 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="@color/grey_300" />
</shape>

Voeg scheidingsteken toe aan uw Recycler-overzicht:

RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecorator(ContextCompat.getDrawable(context, R.drawable.divider));
recyclerView.addItemDecoration(dividerItemDecoration);

Om de scheidingslijn voor het laatste item te verwijderen:

Om te voorkomen dat er scheidingslijnen worden getrokken voor het laatste item, moet u deze regel wijzigen.

for (int i = 0; i < childCount; i++) 

Naar

for (int i = 0; i < childCount-1; i++)

Uw uiteindelijke implementatie zou er als volgt uit moeten zien:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }
    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = parent.getWidth() - parent.getPaddingRight();
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount - 1; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();
            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}

Hopelijk helpt het 🙂


Antwoord 11

Android maakt helaas kleine dingen te ingewikkeld. Gemakkelijkste manier om te bereiken wat je wilt, zonder DividerItemDecoration hier te implementeren:

Voeg achtergrondkleur toe aan de RecyclerView aan de gewenste scheidingskleur:

<RecyclerView
    android:id="@+id/rvList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@color/colorLightGray"
    android:scrollbars="vertical"
    tools:listitem="@layout/list_item"
    android:background="@android:color/darker_gray"/>

Voeg ondermarge (android:layout_marginBottom) toe aan de lay-outhoofdmap van het item (list_item.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:layout_marginBottom="1dp">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="John Doe" />
    <TextView
        android:id="@+id/tvDescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvName"
        android:text="Some description blah blah" />
</RelativeLayout>

Dit zou 1 dp ruimte moeten geven tussen de items en de achtergrondkleur van RecyclerView (die donkergrijs is en als scheidingslijn zou verschijnen).


12

kotlin – Als u op zoek bent naar aangepaste kleurverdeler tussen recycler bekijken items, dan is hier de oplossing die voor mij werkt:

Stap 1: Geef je recycler-weergave een standaard itemdecoratie. recyclerView.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(activity, androidx.recyclerview.widget.LinearLayoutManager.VERTICAL))

Stap 2:
Voeg een XML-tekenbestand toe met vermelding van de grootte – breedte en hoogte met de gewenste kleur.

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/your_color" />
</shape>

Stap 3: voeg deze regel toe aan uw app-thema.

<item name="android:listDivider">@drawable/your_drawable</item>

Antwoord 13

recyclerview.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.HORIZONTAL));

gebruik LinearLayoutManager.VERTICAL voor verticale lijnen


Antwoord 14

Bhuvanesh BS-oplossing werkt. Kotlin-versie hiervan:

import android.graphics.Canvas
import android.graphics.drawable.Drawable
import androidx.recyclerview.widget.RecyclerView
class DividerItemDecorator(private val mDivider: Drawable?) : RecyclerView.ItemDecoration() {
    override fun onDraw(
        canvas: Canvas,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        val dividerLeft = parent.paddingLeft
        val dividerRight = parent.width - parent.paddingRight
        for (i in 0 until parent.childCount - 1) {
            val child = parent.getChildAt(i)
            val dividerTop =
                child.bottom + (child.layoutParams as RecyclerView.LayoutParams).bottomMargin
            val dividerBottom = dividerTop + mDivider!!.intrinsicHeight
            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
            mDivider.draw(canvas)
        }
    }
}

Antwoord 15

Ok, als je de kleur van je scheidingslijn niet hoeft te veranderen, pas dan alpha toe op de scheidingsversieringen.

Voorbeeld voor GridLayoutManager met transparantie:

DividerItemDecoration horizontalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.HORIZONTAL);
        horizontalDividerItemDecoration.getDrawable().setAlpha(50);
        DividerItemDecoration verticalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.VERTICAL);
        verticalDividerItemDecoration.getDrawable().setAlpha(50);
        my_recycler.addItemDecoration(horizontalDividerItemDecoration);
        my_recycler.addItemDecoration(verticalDividerItemDecoration);

Je kunt de kleur van scheidingslijnen nog steeds wijzigen door gewoon de kleur in te stellen
filtert erop.

Voorbeeld voor GridLayoutManager door tint in te stellen:

DividerItemDecoration horizontalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.HORIZONTAL);
        horizontalDividerItemDecoration.getDrawable().setTint(getResources().getColor(R.color.colorAccent));
        DividerItemDecoration verticalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.VERTICAL);
        verticalDividerItemDecoration.getDrawable().setAlpha(50);
        my_recycler.addItemDecoration(horizontalDividerItemDecoration);
        my_recycler.addItemDecoration(verticalDividerItemDecoration);

Bovendien kunt u ook proberen een kleurfilter in te stellen,

horizontalDividerItemDecoration.getDrawable().setColorFilter(colorFilter);

Other episodes