我使用RecyclerView和StaggeredGridLayoutManager制作一个两列列表。但是如何在左列和右列之间设置右边距。我已经使用此代码从顶部创建右边距,但如何解决列之间的双倍空格。
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.
任何人都可以帮助我吗?非常感谢!
答案 0 :(得分:7)
在您的情况下,您可以将两个边距设置为RecyclerView。但在我的情况下,在RecyclerView中有一个与屏幕宽度匹配的图像,我使用ItemDecoration来解决问题。
setup.py develop
答案 1 :(得分:4)
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
);
}
}
}
答案 2 :(得分:3)
我通过设置项目边距和RecyclerView填充来解决这个问题。边距和填充都是预期空间的一半,因此问题消失了。
答案 3 :(得分:0)
我会略微更改并修改相对问题的答案
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;
}
}
}
答案 4 :(得分:0)
根据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设置相同的填充(左/右) 机器人:paddingLeft = “@扪/空间” 机器人:paddingRight = “@扪/空间”
<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"/>
答案 5 :(得分:0)
可以在RecyclerView的两侧设置填充:
myRecyclerView.setPadding(10,0,10,0);
通过这种方式,您可以均衡侧面和列之间的空间。
答案 6 :(得分:0)
我通过以下三个步骤解决了这个问题:
<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())
仅此而已,没有边界/填充硬编码,并且使用Koltin xD
注意:重要的是不要在孩子的视图布局中建立任何水平边距
答案 7 :(得分: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
)
)