StaggeredGridLayoutManagerでRecyclerViewを使用して、2列のリストを作成しています。しかし、左の列と右の列の間に右マージンを設定する方法。私はこのコードを使用して上から右マージンを作成しましたが、列間の二重スペースを解決する方法。
_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 or second item to avoid double space between items
// Add top margin only for the first or second item to avoid double space between items
if((parent.getChildCount() > 0 && parent.getChildPosition(view) == 0)
|| (parent.getChildCount() > 1 && parent.getChildPosition(view) == 1))
outRect.top = space;
}
_
そして活動中:
_recyclerView.addItemDecoration(new SpacesItemDecoration(20));
_
view.getX()
を使おうとしましたが、常に0を返します。
誰か助けてもらえますか?どうもありがとう!
次のコードは、StaggeredGridLayoutManager、GridLayoutManager、およびLinearLayoutManagerを処理します。
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int halfSpace;
public SpacesItemDecoration(int space) {
this.halfSpace = space / 2;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (parent.getPaddingLeft() != halfSpace) {
parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
parent.setClipToPadding(false);
}
outRect.top = halfSpace;
outRect.bottom = halfSpace;
outRect.left = halfSpace;
outRect.right = halfSpace;
}
}
あなたの場合、両方のマージンをRecyclerViewに設定できます。しかし、私の場合、RecyclerViewの画面幅に一致する画像があり、ItemDecorationを使用して問題を解決します。
class ViewItemDecoration extends RecyclerView.ItemDecoration {
public ViewItemDecoration() {
}
@Override
public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
int type = adapter.getItemViewType(position);
switch(type){
case YOUR_ITEMS:
if (spanIndex == 0) {
outRect.left = 10;
outRect.right = 5;
} else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span
outRect.left = 5;
outRect.right = 10;
}
}
}
}
public class EqualGapItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
public EqualGapItemDecoration(int spanCount, int spacing) {
this.spanCount = spanCount;
this.spacing = spacing;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
if (layoutParams.isFullSpan()) {
outRect.set(0, 0, 0, 0);
} else {
int spanIndex = layoutParams.getSpanIndex();
int layoutPosition = layoutParams.getViewLayoutPosition();
int itemCount = parent.getAdapter().getItemCount();
boolean leftEdge = spanIndex == 0;
boolean rightEdge = spanIndex == (spanCount - 1);
boolean topEdge = spanIndex < spanCount;
boolean bottomEdge = layoutPosition >= (itemCount - spanCount);
int halfSpacing = spacing / 2;
outRect.set(
leftEdge ? spacing : halfSpacing,
topEdge ? spacing : halfSpacing,
rightEdge ? spacing : halfSpacing,
bottomEdge ? spacing : 0
);
}
}
}
アイテムのマージンとRecyclerViewのパディングを設定することで自分で解決しました。マージンとパディングの両方が予想されるスペースの半分であるため、問題は解消されました。
RecyclerViewの両側にパディングを設定することができます。
myRecyclerView.setPadding(10,0,10,0);
このようにして、側面と列の間のスペースを均等化できます。
次のコードは、StaggeredGridLayoutを問題なく処理します(少なくとも私の経験から)。 SpaceItemDecoratorにスペースを指定するだけで済みます。
class SpaceItemDecoration(private val spacing: Int) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val lm = parent.layoutManager as StaggeredGridLayoutManager
val lp = view.layoutParams as StaggeredGridLayoutManager.LayoutParams
val spanCount = lm.spanCount
val spanIndex = lp.spanIndex
val positionLayout = lp.viewLayoutPosition
val itemCount = lm.itemCount
val position = parent.getChildAdapterPosition(view)
outRect.right = spacing / 2
outRect.left = spacing / 2
outRect.top = spacing / 2
outRect.bottom = spacing / 2
if (spanIndex == 0) outRect.left = spacing
if (position < spanCount) outRect.top = spacing
if (spanIndex == (spanCount - 1)) outRect.right = spacing
if (positionLayout > (itemCount - spanCount)) outRect.bottom = spacing
}
}
次のようにピクセル単位で間隔を取得できます。
val spacingInPixels = resources.getDimensionPixelSize(R.dimen.grid_layout_margin)
次に、アイテムの装飾をリサイクラービューに割り当てる必要があります。
recycler_view.addItemDecoration(
SpaceItemDecoration(
spacingInPixels
)
)
Spanindexに従ってItemDecorationで異なる左/右スペースを設定すると、アイテムビューのサイズが固定されている場合にのみ適切に機能します。アイテムビューに画像ビューセットwrap_contentの高さが含まれている場合、アイテムビューはスパン位置を変更できますが、スパンインデックスが希望どおりに更新されないため、マージンが乱雑になります。
私のやり方は、ビューアイテムに左右対称のスペースを使用することです。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// init
recyclerView = (RecyclerView) rv.findViewById(R.id.img_waterfall);
layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new MyAdapter(getContext()));
recyclerView.addItemDecoration(new SpacesItemDecoration(
getResources().getDimensionPixelSize(R.dimen.space)));
}
private static class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private final int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
outRect.bottom = 2 * space;
int pos = parent.getChildAdapterPosition(view);
outRect.left = space;
outRect.right = space;
if (pos < 2)
outRect.top = 2 * space;
}
}
次に、RecylerView(左/右)に同じパディングを設定しますAndroid:paddingLeft = "@ dimen/space" Android:paddingRight = "@ dimen/space"
<Android.support.v7.widget.RecyclerView
Android:id="@+id/img_waterfall"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingLeft="@dimen/space"
Android:paddingRight="@dimen/space"/>
相対的な質問の両方の回答を少し変更して変更します
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private final int mSpace;
public SpacesItemDecoration(int space) {
this.mSpace = space;
}
@Override
public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
if (spanIndex == 0) {
outRect.left = 30;
outRect.right = 15;
} else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span
outRect.left = 15;
outRect.right = 30;
}
outRect.bottom = 30;
// Add top margin only for the first item to avoid double space between items
if (parent.getChildAdapterPosition(view) == 0) {
outRect.top = 30;
outRect.right = 30;
}
}
}
私はこれを次の方法で3つのステップで解決しました。
<androidx.recyclerview.widget.RecyclerView
Android:id="@+id/recyclerView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginStart="@dimen/margin_small"
Android:layout_marginEnd="@dimen/margin_small"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:spanCount="2" />
class SpaceItemDecorator : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
val layoutParams = view.layoutParams as StaggeredGridLayoutManager.LayoutParams
val spanIndex = layoutParams.spanIndex
if (spanIndex == 0) {
val marginParentEnd = parent.marginEnd
layoutParams.marginEnd = marginParentEnd / 2
} else {
val marginParentStart = parent.marginStart
layoutParams.marginStart = marginParentStart / 2
}
view.layoutParams = layoutParams
}
}
recyclerview.addItemDecoration(SpaceItemDecorator())
マージン/パディングハードコードなしで、KoltinxDではこれですべてです
注:子のビューレイアウトに水平方向のマージンを設定しないことが重要です