web-dev-qa-db-ja.com

RecyclerViewの項目間に仕切りとスペースを追加するにはどうすればいいですか?

これは、 divider および dividerHeight パラメータを使用して、以前にListViewクラスで実行された方法の例です。

<ListView
    Android:id="@+id/activity_home_list_view"
    Android:layout_width="match_parent" 
    Android:layout_height="match_parent"
    Android:divider="@Android:color/transparent"
    Android:dividerHeight="8dp"/>

しかし、RecyclerViewクラスにはそのような可能性はありません。

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/activity_home_recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:scrollbars="vertical"/>

その場合、マージンを定義したり、カスタムの仕切りビューをリストアイテムのレイアウトに直接追加したりしてもよいですか。それとも、私の目標を達成するためのより良い方法はありますか?

809
EyesClear

2016年10月の更新

Android Support Libraryのバージョン25.0.0で DividerItemDecoration classが導入されました。

DividerItemDecorationはRecyclerView.ItemDecorationで、LinearLayoutManagerの項目間の区切り文字として使用できます。 HORIZONTALVERTICALの両方の向きをサポートします。

使用法:

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

前回の回答

いくつかの回答では、その後廃止予定となっている方法を使用するか、完全な解決策を提示しないので、短くて最新の後処理を試みました。


ListViewとは異なり、RecyclerViewクラスにはディバイダ関連のパラメータはありません。代わりに、ItemDecorationの内部クラスである RecyclerView を拡張する必要があります。

ItemDecorationを使用すると、アプリケーションはアダプタのデータセットの特定の項目ビューに特別な図面とレイアウトのオフセットを追加できます。これは、アイテム間の仕切り、ハイライト、視覚的なグループ化の境界などを描くのに役立ちます。

すべてのItemDecorationsは、項目ビューの前(onDraw())および項目の後(onDrawOver(CanvasRecyclerViewRecyclerView.State))に、追加された順序で描画されます。

Verticalの間隔ItemDecoration

ItemDecorationを拡張し、スペースとしてheightを取るカスタムコンストラクタを追加し、getItemOffsets()メソッドをオーバーライドします。

public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {

    private final int verticalSpaceHeight;

    public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
        this.verticalSpaceHeight = verticalSpaceHeight;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
            RecyclerView.State state) {
        outRect.bottom = verticalSpaceHeight;
    }
}

最後の項目の下にスペースを挿入したくない場合は、次の条件を追加します。

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

注:outRect.topoutRect.left、およびoutRect.rightプロパティを変更して目的の効果を得ることもできます。

除算器ItemDecoration

ItemDecorationを拡張し、onDraw()メソッドをオーバーライドします。

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{Android.R.attr.listDivider};

    private Drawable divider;

    /**
     * Default divider will be used
     */
    public DividerItemDecoration(Context context) {
        final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
        divider = styledAttributes.getDrawable(0);
        styledAttributes.recycle();
    }

    /**
     * Custom divider will be used
     */
    public DividerItemDecoration(Context context, int resId) {
        divider = ContextCompat.getDrawable(context, resId);
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();

        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + divider.getIntrinsicHeight();

            divider.setBounds(left, top, right, bottom);
            divider.draw(c);
        }
    }
}

デフォルトのAndroidディバイダ属性を使用する最初のコンストラクタ、または独自のdrawableを使用する2番目のコンストラクタ、たとえば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>

注:仕切りをoveryour items)に描画する場合は、代わりにonDrawOver()メソッドをオーバーライドしてください。

使用法

新しいクラスを使用するには、たとえばフラグメントのonCreateView()メソッドで、VerticalSpaceItemDecorationDividerSpaceItemDecorationまたはRecyclerViewを追加します。

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

Lucas Rochaのライブラリ もあります。これはアイテムの装飾プロセスを単純化するためのものです。まだ試していません。

その 機能 の中には:

  • 以下を含むストックアイテムの装飾のコレクション。
  • アイテムの間隔水平方向/垂直方向の仕切り。
  • リスト項目
1047
EyesClear

追加するだけ

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

また、依存関係を追加する必要があるかもしれません
compile 'com.Android.support:recyclerview-v7:27.1.0'

編集:

それを少しカスタマイズするために、カスタムドロアブルを追加することができます。

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

例えば、あなたは自由にカスタムドロアブルを使うことができます:

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

Alex FuによるGithubのこの特定のファイルにあなたの注意を向けるかもしれません: https://Gist.github.com/alexfu/0f464fc3742f134ccd1e

これはDividerItemDecoration.Javaサンプルファイルです「サポートデモから直接抜け出した」( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS

私は自分のプロジェクトにこのファイルをインポートした後、仕切り線をうまく取得し、それをリサイクル業者ビューのアイテム装飾として追加することができました。

これは私のonCreateViewがRecyclerviewを含む私のフラグメントの中でどのように見えるかです:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);

    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
    mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    return rootView;
}

私は追加のスタイリングができると確信していますが、それは出発点です。 :)

246
Duy Nguyen

すべての項目間の等間隔のための単純なItemDecoration実装。

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

    public SpacesItemDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = space;
        outRect.right = space;
        outRect.bottom = space;

        // Add top margin only for the first item to avoid double space between items
        if(parent.getChildAdapterPosition(view) == 0) {
            outRect.top = space;
        }
    }
}
144
SergeyA

簡単なのは RecyclerView の背景色とアイテムの異なる背景色を設定することです。これは一例です...

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

そして TextView 項目(それは何でも構いません)は下余白 "x" dpまたはpxです。

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

出力 ...

enter image description here

102
Madan Sapkota

私は簡単なデバイダを使うのがあなたを助けると思う

各項目に仕切りを追加するには:
1-これを描画可能ディレクトリline_divider.xmlに追加します

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

2- SimpleDividerItemDecorationクラスを作成する
この例を使ってこのクラスを定義しました。
https://Gist.github.com/polbins/e37206fbc444207c0e92

package com.example.myapp;
import Android.content.Context;
import Android.content.res.Resources;
import Android.graphics.Canvas;
import Android.graphics.drawable.Drawable;
import Android.support.v7.widget.RecyclerView;
import Android.view.View;
import com.example.myapp.R;

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

public SimpleDividerItemDecoration(Resources resources) {
    mDivider = resources.getDrawable(R.drawable.line_divider);
}

public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    int left = parent.getPaddingLeft();
    int right = parent.getWidth() - parent.getPaddingRight();

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = parent.getChildAt(i);

        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        int top = child.getBottom() + params.bottomMargin;
        int bottom = top + mDivider.getIntrinsicHeight();

        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
  }
}


3- onCreateView内でRecyclerViewを使用するアクティビティまたはフラグメントでは、これを追加します。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
 RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
 myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
 ....
 }


4-項目間にスペースを追加する
アイテムビューにパディングプロパティを追加するだけです。

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent" Android:layout_height="match_parent"
Android:padding="4dp"
>
..... item structure
</RelativeLayout>
40
Belal mazlom

私はItemAnimatorsを設定しました。 ItemDecoratorはアニメーションと一緒に出入りしません。

各アイテムのアイテムビューレイアウトファイルにビュー行を含めることになりました。それは私のケースを解決しました。 DividerItemDecorationは単純な仕切りにとっては手に負えないものだと感じました。

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

Material Designを使用してこれを正しく実装する正しい方法はありませんので、リスト項目に区切り線を直接追加するために次のトリックを実行しました。

<View
Android:layout_width="match_parent"
Android:layout_height="1dp"
Android:background="@color/dividerColor"/>
21
Yoann Hercouet

これは簡単です、あなたはそのような複雑なコードを必要としません

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

これをあなたのdrawableに追加してください:line_divider.xml

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

2016年10月更新

サポートライブラリv25.0.0では、ついに利用可能な基本的な水平方向と垂直方向の仕切りのデフォルト実装があります。

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

14
friday

だれかがアイテム間に10dpの間隔を追加するだけの場合は、drawableをDividerItemDecorationに設定することで追加できます。

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

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

divider_10dpは、次のものを含む描画可能なリソースです。

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle">
    <size Android:height="10dp"/>
    <solid Android:color="@Android:color/transparent"/>
</shape>
13
Praveen Singh
  • これは仕切りを追加する簡単なハックです。
  • 次のようにリサイクル業者のアイテムのレイアウトに背景を追加するだけです。

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

Drawableフォルダに以下のshape_border.xmlを作成してください

  <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
      Android:shape="rectangle" >
       <gradient
        Android:angle="270"
        Android:centerColor="@Android:color/transparent"
        Android:centerX="0.01"
        Android:startColor="#000" />
    </shape>

これが最終結果です - 仕切り付きのRecyclerViewです。

Here is final result - a RecyclerView with divider.

10
turbandroid

これは実際には問題を解決しませんが、一時的な回避策として、XMLレイアウトのカードの useCompatPadding プロパティを設定して、Lollipopより前のバージョンと同じように測定することができます。

card_view:cardUseCompatPadding="true"
9
Kevin Grant

RecyclerView 項目間のスペース だけを探している人のために、私がより大きなパディングを与えた最初と最後の項目を除いて、すべての項目間で等しいスペースを得る私のアプローチを見てください。水平方向のLayoutManagerでは左右に、垂直方向のLayoutManagerでは上下にのみパディングを適用します。

public class PaddingItemDecoration extends RecyclerView.ItemDecoration {

    private int mPaddingPx;
    private int mPaddingEdgesPx;

    public PaddingItemDecoration(Activity activity) {
        final Resources resources = activity.getResources();
        mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault);
        mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        final int itemPosition = parent.getChildAdapterPosition(view);
        if (itemPosition == RecyclerView.NO_POSITION) {
            return;
        }
        int orientation = getOrientation(parent);
        final int itemCount = state.getItemCount();

        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;

        /** HORIZONTAL */
        if (orientation == LinearLayoutManager.HORIZONTAL) {
            /** all positions */
            left = mPaddingPx;
            right = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                left += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                right += mPaddingEdgesPx;
            }
        }
        /** VERTICAL */
        else {
            /** all positions */
            top = mPaddingPx;
            bottom = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                top += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                bottom += mPaddingEdgesPx;
            }
        }

        if (!isReverseLayout(parent)) {
            outRect.set(left, top, right, bottom);
        } else {
            outRect.set(right, bottom, left, top);
        }
    }

    private boolean isReverseLayout(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getReverseLayout();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

dimens.xml

<resources>
    <dimen name="paddingItemDecorationDefault">10dp</dimen>
    <dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
9
Ryan Amaral

あなたの見解に余白を加えてください、それは私のために働きました。

Android:layout_marginTop="10dp"

equal spacing を追加して _ xml _ に追加したい場合は、paddingRecyclerViewを、layoutMarginに展開する項目に同量のRecyclerViewを設定し、背景をそのままにします。色は、間隔の色を決定します。

9
Quantum Mattter

私は古いGistからDividerItemDecorationを分岐し、私のユースケースに合うようにそれを単純化し、そして最後のリスト項目の後のディバイダを含めて、それらがListViewで描かれる方法でディバイダを描くようにそれを修正しました。これは垂直のItemAnimatorアニメーションも処理します。

1)プロジェクトにこのクラスを追加してください。

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{Android.R.attr.listDivider};
    private Drawable divider;

    public DividerItemDecoration(Context context) {
        try {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            divider = a.getDrawable(0);
            a.recycle();
        } catch (Resources.NotFoundException e) {
            // TODO Log or handle as necessary.
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (divider == null) return;
        if (parent.getChildAdapterPosition(view) < 1) return;

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
            outRect.top = divider.getIntrinsicHeight();
        else
            throw new IllegalArgumentException("Only usable with vertical lists");
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (divider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();

        for (int i = 0; i < childCount; ++i) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int size = divider.getIntrinsicHeight();
            final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
            final int bottom = top + size;
            divider.setBounds(left, top, right, bottom);
            divider.draw(c);

            if (i == childCount - 1) {
                final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
                final int newBottom = newTop + size;
                divider.setBounds(left, newTop, right, newBottom);
                divider.draw(c);
            }
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
            throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
        return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
    }
}

2)RecylerViewにデコレータを追加してください。

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
8
Learn OpenGL ES

DividerItemDecorationなどのrecyclerviewに添付されているさまざまなデコレータを使用してアイテムを装飾できます。

単純に以下を使用してください... EyesClear による答えから引用

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{Android.R.attr.listDivider};

private Drawable mDivider;

/**
 * Default divider will be used
 */
public DividerItemDecoration(Context context) {
    final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
    mDivider = styledAttributes.getDrawable(0);
    styledAttributes.recycle();
}

/**
 * Custom divider will be used
 */
public DividerItemDecoration(Context context, int resId) {
    mDivider = ContextCompat.getDrawable(context, resId);
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    int left = parent.getPaddingLeft();
    int right = parent.getWidth() - parent.getPaddingRight();

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = parent.getChildAt(i);

        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        int top = child.getBottom() + params.bottomMargin;
        int bottom = top + mDivider.getIntrinsicHeight();

        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

そして上記のように次のように使います。

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

以下のようにリスト内の各項目間の仕切りが表示されます。

enter image description here

そしてより多くの詳細を探している人のためにこのガイドをチェックすることができます RecyclerViewを使う_ CodePath Android Cliffnotes

ここでのいくつかの答えはマージンの使用を示唆していますが、キャッチはそれです:あなたがトップとボトムの両方のマージンを追加すると、それらはアイテム間で追加されたように見えます。どちらかを追加するだけでは、リスト全体の上部または下部に余白はありません。上部の半分、下部の半分を追加すると、外側の余白が小さくなります。

したがって、審美的に正しい唯一の解決策は、システムがどこに適切に適用するかを知っている仕切りであり、アイテム間ではあるがアイテムの上下ではない。

以下のコメントに疑問があれば教えてください。

5
Anudeep Samaiya

このリンクは私にとって魅力的なものでした。

https://Gist.github.com/lapastillaroja/858caf1a82791b6c1a36

import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Canvas;
import Android.graphics.Rect;
import Android.graphics.drawable.Drawable;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.util.AttributeSet;
import Android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;
    private boolean mShowFirstDivider = false;
    private boolean mShowLastDivider = false;


    public DividerItemDecoration(Context context, AttributeSet attrs) {
        final TypedArray a = context
                .obtainStyledAttributes(attrs, new int[]{Android.R.attr.listDivider});
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
            boolean showLastDivider) {
        this(context, attrs);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    public DividerItemDecoration(Drawable divider) {
        mDivider = divider;
    }

    public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
            boolean showLastDivider) {
        this(divider);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
            RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (mDivider == null) {
            return;
        }
        if (parent.getChildPosition(view) < 1) {
            return;
        }

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
            outRect.top = mDivider.getIntrinsicHeight();
        } else {
            outRect.left = mDivider.getIntrinsicWidth();
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mDivider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        // Initialization needed to avoid compiler warning
        int left = 0, right = 0, top = 0, bottom = 0, size;
        int orientation = getOrientation(parent);
        int childCount = parent.getChildCount();

        if (orientation == LinearLayoutManager.VERTICAL) {
            size = mDivider.getIntrinsicHeight();
            left = parent.getPaddingLeft();
            right = parent.getWidth() - parent.getPaddingRight();
        } else { //horizontal
            size = mDivider.getIntrinsicWidth();
            top = parent.getPaddingTop();
            bottom = parent.getHeight() - parent.getPaddingBottom();
        }

        for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getTop() - params.topMargin;
                bottom = top + size;
            } else { //horizontal
                left = child.getLeft() - params.leftMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

        // show last divider
        if (mShowLastDivider && childCount > 0) {
            View child = parent.getChildAt(childCount - 1);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getBottom() + params.bottomMargin;
                bottom = top + size;
            } else { // horizontal
                left = child.getRight() + params.rightMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException(
                    "DividerItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

それからあなたの活動の中で:

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

フラグメントを使用しているのであれば、これは:

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

グーグル検索から、これを ItemDecoration をあなたのRecyclerViewに追加してください。

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;


public DividerItemDecoration(Context context, AttributeSet attrs) {
    final TypedArray a = context
            .obtainStyledAttributes(attrs, new int[]{Android.R.attr.listDivider});
    mDivider = a.getDrawable(0);
    a.recycle();
}

public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
        boolean showLastDivider) {
    this(context, attrs);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

public DividerItemDecoration(Drawable divider) {
    mDivider = divider;
}

public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
        boolean showLastDivider) {
    this(divider);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
        RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    if (mDivider == null) {
        return;
    }
    if (parent.getChildPosition(view) < 1) {
        return;
    }

    if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
        outRect.top = mDivider.getIntrinsicHeight();
    } else {
        outRect.left = mDivider.getIntrinsicWidth();
    }
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mDivider == null) {
        super.onDrawOver(c, parent, state);
        return;
    }

    // Initialization needed to avoid compiler warning
    int left = 0, right = 0, top = 0, bottom = 0, size;
    int orientation = getOrientation(parent);
    int childCount = parent.getChildCount();

    if (orientation == LinearLayoutManager.VERTICAL) {
        size = mDivider.getIntrinsicHeight();
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
    } else { //horizontal
        size = mDivider.getIntrinsicWidth();
        top = parent.getPaddingTop();
        bottom = parent.getHeight() - parent.getPaddingBottom();
    }

    for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
        View child = parent.getChildAt(i);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getTop() - params.topMargin;
            bottom = top + size;
        } else { //horizontal
            left = child.getLeft() - params.leftMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }

    // show last divider
    if (mShowLastDivider && childCount > 0) {
        View child = parent.getChildAt(childCount - 1);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getBottom() + params.bottomMargin;
            bottom = top + size;
        } else { // horizontal
            left = child.getRight() + params.rightMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

private int getOrientation(RecyclerView parent) {
    if (parent.getLayoutManager() instanceof LinearLayoutManager) {
        LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
        return layoutManager.getOrientation();
    } else {
        throw new IllegalStateException(
                "DividerItemDecoration can only be used with a LinearLayoutManager.");
    }
}
}
5
gatlingxyz

仕切りの高さと色を変更するためにshape xmlを作成する代わりに。あなたはプログラムのように作成することができます

val divider = DividerItemDecoration(context,
        DividerItemDecoration.VERTICAL)

divider.setDrawable(ShapeDrawable().apply {
    intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)
    Paint.color = Color.RED // note: currently (support version 28.0.0), we can not use tranparent color here, if we use transparent, we still see a small divider line. So if we want to display transparent space, we can set color = background color or we can create a custom ItemDecoration instead of DividerItemDecoration. 
})

recycler_devices.addItemDecoration(divider)
4
Phan Van Linh

XMLを使用しない単純なコードベースの回答が必要だと私は感じます

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

ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());

int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);
shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);
shapeDrawableForDivider.setAlpha(0);

dividerItemDecoration.setDrawable(shapeDrawableForDivider);

recyclerView.addItemDecoration(dividerItemDecoration);
4
Boober Bunz

遅すぎますがGridLayoutManagerにします。

public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
    private int space;

    public GridSpacesItemDecoration(int space) {
        this.space = space;
    }

    public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        var position = parent.GetChildLayoutPosition(view);

        /// Only for GridLayoutManager Layouts
        var manager = parent.GetLayoutManager() as GridLayoutManager;

        if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
            outRect.Top = space;

        if (position % 2 != 0) {
            outRect.Right = space;
        }

        outRect.Left = space;
        outRect.Bottom = space;
    }
}

これはあなたが持っているスパンの数に関係なく働きます。

Ollie。

4
Ollie Strevel

アイテムに同じスペースを追加する場合は、最も簡単な方法は、RecycleViewの上部+左の余白とカードアイテムの右+下部の余白を追加することです。

dimens.xml

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

list_item.xml

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

list.xml

<RecyclerView
 Android:paddingLeft="@dimen/divider"
 Android:paddingTop="@dimen/divider"
/>
4
limitium

プログラムで簡単に追加できます。

レイアウトマネージャがLinearlayoutの場合は、次のものを使用できます。

DividerItemDecorationは、LinearLayoutManagerの項目間の仕切りとして使用できるRecyclerView.ItemDecorationです。それは水平方向と垂直方向の両方をサポートしています。

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

ソース

4
Beyaz
public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {
    private int mSpace = 0;
    private boolean mVerticalOrientation = true;

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

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

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


    }
}

これにより、すべてのアイテムの上下(または左右)にスペースが追加されます。その後、それをrecyclerViewに設定できます。

recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));

SizeUtils.Java

public class SizeUtils {
    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
3
wizChen

1.方法の1つは、cardviewとrecyclerビューを一緒に使用することです、簡単に仕切りのような効果を追加できます。例. https://developer.Android.com/training/material/lists-cards.html

2.and otherは、viewをリサイクラビューのlist_item_layoutに仕切りとして追加することです

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

以下のようにリスト項目に行を追加しました

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

1pxは細い線を引きます。

最後の行の分割線を非表示にしたい場合は、最後のリストItemのonBindViewHolderのdivider.setVisiblity(View.GONE);を使用します。

3
Raja Peela

独自のRecyclerView.ItemDecorationを実装します。

public class SpacingItemDecoration extends RecyclerView.ItemDecoration {
    private int spacingPx;
    private boolean addStartSpacing;
    private boolean addEndSpacing;

    public SpacingItemDecoration(int spacingPx) {
        this(spacingPx, false, false);
    }

    public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) {
        this.spacingPx = spacingPx;
        this.addStartSpacing = addStartSpacing;
        this.addEndSpacing = addEndSpacing;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (spacingPx <= 0) {
            return;
        }

        if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.top = spacingPx;
            } else {
                outRect.left = spacingPx;
            }
        }

        if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.bottom = spacingPx;
            } else {
                outRect.right = spacingPx;
            }
        }
    }

    private int getTotalItemCount(RecyclerView parent) {
        return parent.getAdapter().getItemCount();
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        } else {
            throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}
2
e.shishkin

本当に簡単な解決策は RecyclerView-FlexibleDividerを使うことです

依存関係を追加します。

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

あなたのrecyclerviewに加えなさい:

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

そしてこれで終わりです!

2
Cristan

RecyclerViewListViewとは少し異なります。実際、RecyclerViewはその中にListViewのような構造を必要とします。たとえば、LinearLayoutです。 LinearLayoutは各要素を分割するためのパラメータを持ちます。以下のコードで、私はRecyclerView内のCardViewオブジェクトで構成されたLinearLayoutを持っています。これは項目間にスペースを入れるでしょう。そのスペースを本当に小さくしてください。

これはrecyclerview_layout.xmlの中のRecyclerビューです。

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

そして、ここで各項目がどのように見えるか(そしてそれはAndroidのために分割されて表示されます:すべてを囲むLinearLayoutのパディング):cards_layout.xml

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

PrimeAdapter

PrimeAdapter を使用することで、RecyclerViews内の仕切りの扱いはとても簡単になります。仕切りを作成および管理するための複数の機能とより高い柔軟性を提供します。

以下のようにしてアダプタを作成することができます。( github で使用法に関する完全な文書をご覧ください)

val adapter = PrimeAdapter.with(recyclerView)
                    .setLayoutManager(LinearLayoutManager(activity))
                    .set()
                    .build(ActorAdapter::class.Java)

アダプタインスタンスを作成した後は、次のようにして簡単にディバイダを追加できます。

//----- default divider:
adapter.setDivider()

//----- divider with custom drawable:
adapter.setDivider(ContextCompat.getDrawable(context, R.drawable.divider))

//----- divider with custom color:
adapter.setDivider(Color.RED)

//----- divider with custom color and custom inset:
adapter.setDivider(Color.RED, insetLeft = 16, insetRight = 16)

//----- deactivate dividers:
adapter.setDivider(null)

enter image description here

1
aminography

このクラスを使用して、あなたのRecyclerView内に区切り文字を設定します。

 public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

        private int spanCount;
        private int spacing;
        private boolean includeEdge;

        public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
            this.spanCount = spanCount;
            this.spacing = spacing;
            this.includeEdge = includeEdge;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view); // item position
            int column = position % spanCount; // item column

            if (includeEdge) {
                outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
                outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

                if (position < spanCount) { // top Edge
                    outRect.top = spacing;
                }
                outRect.bottom = spacing; // item bottom
            } else {
                outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
                outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
                if (position >= spanCount) {
                    outRect.top = spacing; // item top
                }
            }
        }
    }
1
Makvin
public class VerticalItemDecoration extends RecyclerView.ItemDecoration {

private boolean verticalOrientation = true;
private int space = 10;

public VerticalItemDecoration(int value, boolean verticalOrientation) {
    this.space = value;
    this.verticalOrientation = verticalOrientation;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                           RecyclerView.State state) {
    //skip first item in the list
    if (parent.getChildAdapterPosition(view) != 0) {
        if (verticalOrientation) {
            outRect.set(space, 0, 0, 0);
        } else if (!verticalOrientation) {
            outRect.set(0, space, 0, 0);
        }
    }
}
}

mCompletedShippingRecyclerView.addItemDecoration(new VerticalItemDecoration(20,false)); 
1
Amardeep

RecyclerViewに分割線を追加する非常に簡単な方法があります。カスタムアダプタを使用してリサイクラビューのレイアウトを変更し、リサイクラビューの項目と共に背景色(仕切りの色になる)でLinearLayoutを追加し、親に合わせて高さ1dp(または要件に応じて)および幅を追加します。 。

これがサンプルコードです。

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

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="horizontal"
    Android:padding="18dp">

    <TextView
        Android:id="@+id/list_row_SNO"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight=".8"
        Android:layout_gravity="end"
        Android:text="44."
        Android:textAlignment="center"
        Android:textSize="24sp"
        Android:textColor="@color/colorBlack"
        Android:fontFamily="sans-serif-condensed" />

    <TextView
        Android:id="@+id/list_row_Heading"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight=".2"
        Android:layout_gravity="start"
        Android:text="Student's application for leave and this what"
        Android:textAlignment="textStart"
        Android:textSize="24sp"
        Android:textColor="@color/colorBlack"
        Android:fontFamily="sans-serif-condensed" />

</LinearLayout>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="1dp"
    Android:background="@color/colorHighlight">
</LinearLayout>
1
Nabajyoti Das

これが私の怠惰なアプローチですが、それはうまくいきます:CardViewをレイアウトにラップして、親レイアウトにパディング/マージンを設定してディバイダをまねて、そして通常のディバイダをnullに強制する

list_item.xml

<LinearLayout
    Android:id="@+id/entry_item_layout_container"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    Android:paddingBottom="<divider_size>" > // this is the divider
    <CardView
        Android:layout_width="<width_size>"
        Android:layout_height="<height_size>">
        ...
    </CardView>
</LinearLayout

list.xml

<RecyclerView
 Android:divider="@null"
 Android:layout_width="<width_size>"
 Android:layout_height="<height_size>"
 ...
/>
0
kip2

RecyclerViewは、リストの仕切りを描画するための分かりやすいインターフェースを提供していません。しかし実際には、仕切りを引くためのはるかに柔軟な方法を提供しています。 RecyclerView.ItemDecoration を使用して、RecyclerViewのタイルを仕切りなどで装飾します。それがItemDecorationと呼ばれる理由でもあります。

材料設計ガイドライン に記載されているように:

仕切りはタイルのベースライン内にあります。

そのため、材料設計ガイドラインに従いたい場合は、仕切りを描くための余分なスペースは必要ありません。タイルの上に描くだけです。しかし、あなたはあなたがやりたいことは何でもする権利があります。それで私はあなたにインセットを設定する能力とタイルの上/下に描く能力を与えるものを実装しました。

public class InsetDivider extends RecyclerView.ItemDecoration {

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Paint mPaint;
    // in pixel
    private int mDividerHeight;
    // left inset for vertical list, top inset for horizontal list
    private int mFirstInset;
    // right inset for vertical list, bottom inset for horizontal list
    private int mSecondInset;
    private int mColor;
    private int mOrientation;
    // set it to true to draw divider on the tile, or false to draw beside the tile.
    // if you set it to false and have inset at the same time, you may see the background of
    // the parent of RecyclerView.
    private boolean mOverlay;

    private InsetDivider() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
    }

    public int getDividerHeight() {
        return mDividerHeight;
    }

    public void setDividerHeight(int dividerHeight) {
        this.mDividerHeight = dividerHeight;
    }

    public int getFirstInset() {
        return mFirstInset;
    }

    public void setFirstInset(int firstInset) {
        this.mFirstInset = firstInset;
    }

    public int getSecondInset() {
        return mSecondInset;
    }

    public void setSecondInset(int secondInset) {
        this.mSecondInset = secondInset;
    }

    public int getColor() {
        return mColor;
    }

    public void setColor(int color) {
        this.mColor = color;
        mPaint.setColor(color);
    }

    public int getOrientation() {
        return mOrientation;
    }

    public void setOrientation(int orientation) {
        this.mOrientation = orientation;
    }

    public boolean getOverlay() {
        return mOverlay;
    }

    public void setOverlay(boolean overlay) {
        this.mOverlay = overlay;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    protected void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft() + mFirstInset;
        final int right = parent.getWidth() - parent.getPaddingRight() - mSecondInset;
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {
                continue;
            }
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int bottom;
            final int top;
            if (mOverlay) {
                bottom = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
                top = bottom - mDividerHeight;
            } else {
                top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
                bottom = top + mDividerHeight;
            }
            c.drawRect(left, top, right, bottom, mPaint);
        }
    }

    protected void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop() + mFirstInset;
        final int bottom = parent.getHeight() - parent.getPaddingBottom() - mSecondInset;
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {
                continue;
            }
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
            final int right;
            final int left;
            if (mOverlay) {
                right = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
                left = right - mDividerHeight;
            } else {
                left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
                right = left + mDividerHeight;
            }
            c.drawRect(left, top, right, bottom, mPaint);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOverlay) {
            super.getItemOffsets(outRect, view, parent, state);
            return;
        }

        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDividerHeight);
        } else {
            outRect.set(0, 0, mDividerHeight, 0);
        }
    }

    /**
     * Handy builder for creating {@link InsetDivider} instance.
     */
    public static class Builder {

        private Context mContext;
        private int mDividerHeight;
        private int mFirstInset;
        private int mSecondInset;
        private int mColor;
        private int mOrientation;
        private boolean mOverlay = true; // set default to true to follow Material Design Guidelines

        public Builder(Context context) {
            mContext = context;
        }

        public Builder dividerHeight(int dividerHeight) {
            mDividerHeight = dividerHeight;
            return this;
        }

        public Builder insets(int firstInset, int secondInset) {
            mFirstInset = firstInset;
            mSecondInset = secondInset;
            return this;
        }

        public Builder color(@ColorInt int color) {
            mColor = color;
            return this;
        }

        public Builder orientation(int orientation) {
            mOrientation = orientation;
            return this;
        }

        public Builder overlay(boolean overlay) {
            mOverlay = overlay;
            return this;
        }

        public InsetDivider build() {
            InsetDivider insetDivider = new InsetDivider();

            if (mDividerHeight == 0) {
                // Set default divider height to 1dp.
                 insetDivider.setDividerHeight(mContext.getResources().getDimensionPixelSize(R.dimen.divider_height));
            } else if (mDividerHeight > 0) {
                insetDivider.setDividerHeight(mDividerHeight);
            } else {
                throw new IllegalArgumentException("Divider's height can't be negative.");
            }

            insetDivider.setFirstInset(mFirstInset < 0 ? 0 : mFirstInset);
            insetDivider.setSecondInset(mSecondInset < 0 ? 0 : mSecondInset);

            if (mColor == 0) {
                throw new IllegalArgumentException("Don't forget to set color");
            } else {
                insetDivider.setColor(mColor);
            }

            if (mOrientation != InsetDivider.HORIZONTAL_LIST && mOrientation != InsetDivider.VERTICAL_LIST) {
                throw new IllegalArgumentException("Invalid orientation");
            } else {
                insetDivider.setOrientation(mOrientation);
            }

            insetDivider.setOverlay(mOverlay);

            return insetDivider;
        }
    }
}

そして、あなたはこのようにそれを使うことができます:

ItemDecoration divider = new InsetDivider.Builder(this)
                            .orientation(InsetDivider.VERTICAL_LIST) 
                            .dividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height))
                            .color(getResources().getColor(R.color.colorAccent))
                            .insets(getResources().getDimensionPixelSize(R.dimen.divider_inset), 0)
                            .overlay(true)
                            .build(); 

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(divider);

ItemDecorationの実装方法とそれらの使用方法についてのデモAppも書きました。あなたは私のGitHubリポジトリ Dividers-For-RecyclerView をチェックアウトすることができます。その中に3つの実装があります。

  • UnderneathDivider
  • オーバーレイディバイダ
  • インセットディバイダ
0
Jiaheng