Android RecyclerViewに分割線を追加するにはどうすればよいですか?


221

私が使用しているAndroidアプリケーションを開発していRecyclerViewます。私は追加する必要が仕切りをしてRecyclerView。追加しようとしました-

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

以下は私のxmlコードです-

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

3
私は、これはあなたを助けるguees stackoverflow.com/q/24618829/942224
Sanket Kachhela

最終行なしでディバイダーを表示するには、これを
Kishan Solanki

あなたのコードは正しいと思います。問題ありません。
Rohit Rawat

回答:


282

2016年10月のアップデートで、サポートライブラリv25.0.0に、基本的な水平および垂直の仕切りのデフォルト実装が追加されました。

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

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

3
情報ありがとうございます。最後のアイテムの後に仕切りを削除する方法はありますか?リストが実装されているCardViewがあるだけで、下部のcardviewのディバイダー+シャドウは良くありません。
2016年

4
私は同じ問題を抱えており、DividerItemDecorationを拡張してgetItemOffsetsをオーバーライドすることで解決し、最初の項目にいない場合にのみsuperを呼び出します。if(parent.getChildAdapterPosition(view) == state.getItemCount() - 1)次に戻り、そうでなければスーパークラスを呼び出しますgetItemOffsets()
ロビン

13
の代わりにmLayoutManager.getOrientation()DividerItemDecoration.VERTICALRecyclerViewが垂直なので、使用して機能しました。
アーロンLelevier

2
この組み込みの方法を使用してディバイダーの色を変更する方法はありますか?
j2emanue 2017年

1
@android:attr/listDividerアプリテーマの@ V.Kalyuzhnyu がカラーリソースの場合、仕切りが表示されません。固定の高さで自分の色でドローアブルを作成する必要がありました。
A. Ferrand

226

正しい方法は次のように定義ItemDecorationすることRecyclerViewです

SimpleDividerItemDecoration.java

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public SimpleDividerItemDecoration(Context context) {
        mDivider = context.getResources().getDrawable(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);
        }
    }
}

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>

最後にこのように設定します

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));

編集する

@Alan Solitarが指摘したように

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

代わりに減価償却されます

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

3
context.getResources()。getDrawable(R.drawable.line_divider)は非推奨になりました。
アランS.

2
問題ない。これは良い答えであり、私にとっては完璧に機能しました。ありがとうございました。
アランS.

3
これは完全に私の側で働いています。ただし、なぜこのセパレーターの単純な<View>を各セルのレイアウトに追加しないのでしょうか。そのはるかに少ないコード。このソリューションは、賢明なパフォーマンスよりも劣っていますか?tx
グレッグ、

4
この実装の問題は、アイテムをスワイプまたは移動しようとすると発生します。
TerNovi 2016年

1
@NJありがとう、あなたは私の時間を節約してくれました。
Suhas Bachewar 2017年

40

水平と垂直の両方の仕切りが必要な場合:

  1. 水平および垂直の仕切りのドローアブルを定義します。

    horizo​​ntal_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. 以下にこのコードセグメントを追加します。

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

出来た。しかし、あなたが変更された場合horizo​​ntal_divider.xmlを分割幅とにvertical_divider.xml除算の高さに、あなたはそれぞれを作成することができDividerItemDecoration、このように:verticalDecoration = new DividerItemDecoration(recyclerview.getContext(), DividerItemDecoration.VERTICAL);horizontalDecoration = new DividerItemDecoration(recyclerview.getContext(), DividerItemDecoration.HORIZONTAL);
Ruben O. Chiavone

33

これらの答えはすべて私に近づきましたが、それぞれ重要な詳細がありませんでした。少し調べた後、私はこれらの3つのステップを組み合わせることが最も簡単な方法だとわかりました。

  1. サポートライブラリのDividerItemDecorationを使用する
  2. 適切な色の仕切りを作成する
  3. このディバイダーをテーマにリストとして設定します

手順1:R​​ecyclerViewの構成中

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

ステップ2: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>

ステップ3:アプリのテーマ

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

編集:最後の仕切りをスキップするように更新:
これを少し使用した後、最後のアイテムの後に仕切りを描くのは面倒でした。そこで、ステップ1を次のように変更して、DividerItemDecorationのデフォルトの動作をオーバーライドします(もちろん、個別のクラスを作成することも別のオプションです)。

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

7
getItemOffsetsをオーバーライドしてもうまくいかないようです。私がオーバーライドしてsuperを呼び出さない場合でも、ディバイダーは描画されます。何が変わったのかわかりません。
lostintranslation 2017年

2
それも私にはうまくいきません。最後の仕切りがまだ表示されています。
ソッティ2018

1
結局、DividerItemDecorationのソースをコピーして独自のディバイダークラスを作成し、最後の除算子を描画しないように少し変更しました。描画メソッドでは、最後の子ビューを無視するだけです。次のように for (int i = 0; i < childCount; i++) 変更しますfor (int i = 0; i < childCount - 1; i++)
kientux

ItemDecorationはリストアイテムの前( "アンダー"リストアイテム)に描画されるため、与えられたソリューションは、リストアイテムが100%不透明な背景である場合、または装飾ドローアブルが100%透明である場合にのみ機能します(ユーザーにrecyclerViewの背景が表示されます)。そうしないと、getItemOffsets()で何を返してもディバイダーが表示されます
ernazm 2018年

31

アイテムアダプターの終わりまでにビューを追加するだけです。

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

25
このソリューションでは、リストの最後に分割線も表示されます。
アリア2016年

5
最後の行は、onBindViewHolderで次のように言うことでプログラムで削除できます。if(position == getItemCount() - 1) { mDividerView.setVisibility(View.INVISIBLE) }または、これを行うには他の方法が必要です。
Ali Kazi 2016

ほとんどの場合、1px高さの最後の行は目に見えません
Mehdi Khademloo

@LucasDiegoこれは機能しますが、膨張は高価であることはわかっています。
ゾーラカーン2018

21

シンプルなカスタムディバイダーのコードは次のとおりです(垂直ディバイダー/ 1 dp高さ/黒):

Support Libraryがあるとします。

compile "com.android.support:recyclerview-v7:25.1.1"

Javaコード

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

次に、custom_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>

10

res / drawableフォルダーに別の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>

次のように、メインアクティビティでxmlファイル(your_file)を接続します。

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

パディングを追加するには?形状にパディングを使用しても機能しません。
Makalele 2017年


8

あなたはFragments持っていると思いますRecyclerView

RecyclerViewand LayoutManagerオブジェクトを作成した後、これらの行を追加するだけです

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

それでおしまい!

水平方向と垂直方向の両方をサポートしています。


8

この単純な1行のコードを試してください

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

7

次の行を追加する必要があります...

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

7

DividerビューとDivider Insetsを処理する方法は、RecyclerView拡張機能を追加することです。

1。

ViewまたはRecyclerViewに名前を付けて、新しい拡張ファイルを追加します。

RecyclerViewExtension.kt

そしてsetDivider、RecyclerViewExtension.ktファイル内に拡張メソッドを追加します。

/*
* RecyclerViewExtension.kt
* */
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView


fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {
    val divider = DividerItemDecoration(
        this.context,
        DividerItemDecoration.VERTICAL
    )
    val drawable = ContextCompat.getDrawable(
        this.context,
        drawableRes
    )
    drawable?.let {
        divider.setDrawable(it)
        addItemDecoration(divider)
    }
}

2。

次のdrawableようにパッケージ内にドローアブルリソースファイルを作成しますrecycler_view_divider.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="10dp"
    android:insetRight="10dp">

    <shape>
        <size android:height="0.5dp" />
        <solid android:color="@android:color/darker_gray" />
    </shape>

</inset>

どこに左右指定することができますマージンをandroid:insetLeftandroid:insetRight

3。

RecyclerViewが初期化されているアクティビティまたはフラグメントで、次を呼び出してカスタムドローアブルを設定できます。

recyclerView.setDivider(R.drawable.recycler_view_divider)

4。

乾杯🍺

仕切り付きのRecyclerView行。


6

したがって、これは正しい方法ではない可能性がありますが、次のように、RecyclerViewの単一アイテムビューにビューを追加しました(組み込み関数はないと思います)。

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

これは、各アイテムの下部に線が入ることを意味します。#111111背景を付けて高さ約1 dpにしました。これにより、一種の「3D」効果も得られます。


2
-これは方法ではありません
Anand Tiwari 2016

5

単純な再利用可能な仕切りを作成できます。

仕切りを作成します。

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

仕切り線を作成します。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>

Recyclerviewにディバイダーを追加します。

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

最後のアイテムの仕切りを削除するには:

最後のアイテムのディバイダー描画を防ぐには、この行を変更する必要があります。

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

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

最終的な実装は次のようになります。

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

それが役に立てば幸い:)


1
これは、それが受け入れられた答えではない理由を完全に私にはわからない作品
ケネディKambo

2

yqritcのRecyclerView-FlexibleDividerは、これを1つのライナーにします。まずこれをあなたに追加してくださいbuild.gradle

compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' // requires jcenter()

これで、recyclerViewのアダプターを設定する場所にdivderを構成して追加できます。

recyclerView.setAdapter(myAdapter);
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this).color(Color.RED).sizeResId(R.dimen.divider).marginResId(R.dimen.leftmargin, R.dimen.rightmargin).build());

16
@Gaurav、HorizontalDividerItemDecorationクラスはどこにありますか?
iRuth

@ iRuth、Mavenライブラリを.gradleファイルに追加する必要がありますgithub.com/yqritc/RecyclerView-FlexibleDivider
Hakem Zaied

5
これは不完全な答えです。おそらく、反対票が適切でしょう。
週末

これの良い3 -サードパーティlibには、その@のGaurav-vachhaniのために必要なことは言うまでも
アンドリュー・V.

2

Androidは残念ながらちょっとしたことを複雑にしすぎます。ここでDividerItemDecorationを実装せずに、目的を達成する最も簡単な方法:

RecyclerViewの背景色を目的の仕切りの色に追加します。

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

下余白(android:layout_marginBottom)をアイテム(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>

これにより、アイテムとRecyclerViewの背景色の間に1 dpのスペースができます(暗い灰色は仕切りとして表示されます)。


1

NJの答えを少し簡単にするために、次のことができます。

public class DividerColorItemDecoration extends DividerItemDecoration {

    public DividerColorItemDecoration(Context context, int orientation) {
        super(context, orientation);
        setDrawable(ContextCompat.getDrawable(context, R.drawable.line_divider));
    }
}

1

のアイテムの下部にx量のマージンを追加するだけRecycleView Adapterです。

onCreateViewHolder

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(0, 0, 0, 5);
itemView.setLayoutParams(layoutParams);

1
recyclerview.addItemDecoration(new DividerItemDecoration(this, 0));

0水平と1垂直はどこですか


3
サポートライブラリの将来のリリースで値が変更される可能性があるため、定数変数を使用することをお
勧めし

true .. 0または1ではなく、LinearLayoutManager.HORIZONTALまたはLinearLayoutManager.VERTICALを使用する必要がある
Freny Christian

0
  class ItemOffsetDecoration(
        context: Context,
        private val paddingLeft: Int,
        private val paddingRight: Int
    ) : RecyclerView.ItemDecoration() {
        private var mDivider: Drawable? = null

        init {
            mDivider = ContextCompat.getDrawable(context, R.drawable.divider_medium)
        }

        override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
            val left = parent.paddingLeft + paddingLeft
            val right = parent.width - parent.paddingRight - paddingRight
            val childCount = parent.childCount
            for (i in 0 until childCount) {
                val child = parent.getChildAt(i)
                val params = child.layoutParams as RecyclerView.LayoutParams
                val top = child.bottom + params.bottomMargin
                val bottom = top + (mDivider?.intrinsicHeight ?: 0)

                mDivider?.let {
                    it.setBounds(left, top, right, bottom)
                    it.draw(c)
                }
            }
        }
    }

R.drawable.divider_mediumで色を指定するだけです

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

</shape>

それをrecyclerViewに追加します

recyclerView.addItemDecoration(
                        ItemOffsetDecoration(
                            this,
                            resources.getDimension(resources.getDimension(R.dimen.dp_70).roundToInt()).roundToInt(),
                            0
                        )
                    )

refernce これを


0

Bhuvanesh BSソリューションが機能します。これのKotlinバージョン:

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

0

私はそれが最も簡単な方法だと思います

mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                DividerItemDecoration.VERTICAL);
// or DividerItemDecoration.HORIZONTALL
        mDividerItemDecoration.setDrawable(getDrawable(R.drawable.myshape));
        recyclerView.addItemDecoration(mDividerItemDecoration);

注: myshapeは、仕切りにしたい高さの長方形にすることができます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.