これは、 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"/>
その場合、マージンを定義したり、カスタムの仕切りビューをリストアイテムのレイアウトに直接追加したりしてもよいですか。それとも、私の目標を達成するためのより良い方法はありますか?
2016年10月の更新
Android Support Libraryのバージョン25.0.0で DividerItemDecoration
classが導入されました。
DividerItemDecorationはRecyclerView.ItemDecorationで、
LinearLayoutManager
の項目間の区切り文字として使用できます。HORIZONTAL
とVERTICAL
の両方の向きをサポートします。
使用法:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
前回の回答
いくつかの回答では、その後廃止予定となっている方法を使用するか、完全な解決策を提示しないので、短くて最新の後処理を試みました。
ListView
とは異なり、RecyclerView
クラスにはディバイダ関連のパラメータはありません。代わりに、ItemDecoration
の内部クラスである RecyclerView
を拡張する必要があります。
ItemDecoration
を使用すると、アプリケーションはアダプタのデータセットの特定の項目ビューに特別な図面とレイアウトのオフセットを追加できます。これは、アイテム間の仕切り、ハイライト、視覚的なグループ化の境界などを描くのに役立ちます。すべての
ItemDecorations
は、項目ビューの前(onDraw()
)および項目の後(onDrawOver(Canvas
、RecyclerView
、RecyclerView.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.top
、outRect.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()
メソッドで、VerticalSpaceItemDecoration
にDividerSpaceItemDecoration
または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のライブラリ もあります。これはアイテムの装飾プロセスを単純化するためのものです。まだ試していません。
その 機能 の中には:
追加するだけ
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>
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;
}
私は追加のスタイリングができると確信していますが、それは出発点です。 :)
すべての項目間の等間隔のための単純な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;
}
}
}
簡単なのは 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"/>
出力 ...
私は簡単なデバイダを使うのがあなたを助けると思う
各項目に仕切りを追加するには:
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>
私は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"/>
Material Designを使用してこれを正しく実装する正しい方法はありませんので、リスト項目に区切り線を直接追加するために次のトリックを実行しました。
<View
Android:layout_width="match_parent"
Android:layout_height="1dp"
Android:background="@color/dividerColor"/>
これは簡単です、あなたはそのような複雑なコードを必要としません
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>
サポートライブラリv25.0.0では、ついに利用可能な基本的な水平方向と垂直方向の仕切りのデフォルト実装があります。
https://developer.Android.com/reference/Android/support/v7/widget/DividerItemDecoration.html
だれかがアイテム間に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>
次のようにリサイクル業者のアイテムのレイアウトに背景を追加するだけです。
<?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です。
これは実際には問題を解決しませんが、一時的な回避策として、XMLレイアウトのカードの useCompatPadding プロパティを設定して、Lollipopより前のバージョンと同じように測定することができます。
card_view:cardUseCompatPadding="true"
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>
あなたの見解に余白を加えてください、それは私のために働きました。
Android:layout_marginTop="10dp"
equal spacing を追加して _ xml _ に追加したい場合は、padding
にRecyclerView
を、layoutMargin
に展開する項目に同量のRecyclerView
を設定し、背景をそのままにします。色は、間隔の色を決定します。
私は古い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()));
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);
以下のようにリスト内の各項目間の仕切りが表示されます。
そしてより多くの詳細を探している人のためにこのガイドをチェックすることができます RecyclerViewを使う_ CodePath Android Cliffnotes
ここでのいくつかの答えはマージンの使用を示唆していますが、キャッチはそれです:あなたがトップとボトムの両方のマージンを追加すると、それらはアイテム間で追加されたように見えます。どちらかを追加するだけでは、リスト全体の上部または下部に余白はありません。上部の半分、下部の半分を追加すると、外側の余白が小さくなります。
したがって、審美的に正しい唯一の解決策は、システムがどこに適切に適用するかを知っている仕切りであり、アイテム間ではあるがアイテムの上下ではない。
以下のコメントに疑問があれば教えてください。
このリンクは私にとって魅力的なものでした。
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));
グーグル検索から、これを 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.");
}
}
}
仕切りの高さと色を変更するために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)
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);
遅すぎますが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。
アイテムに同じスペースを追加する場合は、最も簡単な方法は、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"
/>
プログラムで簡単に追加できます。
レイアウトマネージャがLinearlayoutの場合は、次のものを使用できます。
DividerItemDecorationは、LinearLayoutManagerの項目間の仕切りとして使用できるRecyclerView.ItemDecorationです。それは水平方向と垂直方向の両方をサポートしています。
mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
mLayoutManager.getOrientation());
recyclerView.addItemDecoration(mDividerItemDecoration);
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);
}
}
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" />
以下のようにリスト項目に行を追加しました
<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);
を使用します。
独自の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.");
}
}
}
本当に簡単な解決策は RecyclerView-FlexibleDividerを使うことです
依存関係を追加します。
compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'
あなたのrecyclerviewに加えなさい:
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());
そしてこれで終わりです!
RecyclerView
はListView
とは少し異なります。実際、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>
PrimeAdapter
PrimeAdapter を使用することで、RecyclerView
s内の仕切りの扱いはとても簡単になります。仕切りを作成および管理するための複数の機能とより高い柔軟性を提供します。
以下のようにしてアダプタを作成することができます。( 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)
このクラスを使用して、あなたの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
}
}
}
}
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));
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>
これが私の怠惰なアプローチですが、それはうまくいきます: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>"
...
/>
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つの実装があります。