如何使用GridLayoutManager与RecyclerView设置列间距? 在我的布局中设置空白/填充没有效果。
当前回答
对我来说,完美的解决方案是设置RecyclerView的宽度它的layoutmanager为GridLayoutManager为wrap_content
其他回答
选择的答案几乎是完美的,但根据空间的不同,项目的宽度可能不相等。(对我来说,这很关键)。所以我最终用这个代码增加了一点空间,所以项目都是相同的宽度。
class GridSpacingItemDecoration(private val columnCount: Int, @Px preferredSpace: Int, private val includeEdge: Boolean): RecyclerView.ItemDecoration() {
/**
* In this algorithm space should divide by 3 without remnant or width of items can have a difference
* and we want them to be exactly the same
*/
private val space = if (preferredSpace % 3 == 0) preferredSpace else (preferredSpace + (3 - preferredSpace % 3))
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State?) {
val position = parent.getChildAdapterPosition(view)
if (includeEdge) {
when {
position % columnCount == 0 -> {
outRect.left = space
outRect.right = space / 3
}
position % columnCount == columnCount - 1 -> {
outRect.right = space
outRect.left = space / 3
}
else -> {
outRect.left = space * 2 / 3
outRect.right = space * 2 / 3
}
}
if (position < columnCount) {
outRect.top = space
}
outRect.bottom = space
} else {
when {
position % columnCount == 0 -> outRect.right = space * 2 / 3
position % columnCount == columnCount - 1 -> outRect.left = space * 2 / 3
else -> {
outRect.left = space / 3
outRect.right = space / 3
}
}
if (position >= columnCount) {
outRect.top = space
}
}
}
}
上面的回答已经阐明了设置边缘处理GridLayoutManager和LinearLayoutManager的方法。
但是对于StaggeredGridLayoutManager, Pirdad Sakhizada的回答是:“它可能不太适合StaggeredGridLayoutManager”。应该是关于IndexOfSpan的问题。
您可以通过以下方式获取:
private static class MyItemDecoration extends RecyclerView.ItemDecoration {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int index = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
}
}
如果你想在所有设备中固定你的RecyclerView项的大小。你可以这样做
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int mSpanCount;
private float mItemSize;
public GridSpacingItemDecoration(int spanCount, int itemSize) {
this.mSpanCount = spanCount;
mItemSize = itemSize;
}
@Override
public void getItemOffsets(final Rect outRect, final View view, RecyclerView parent,
RecyclerView.State state) {
final int position = parent.getChildLayoutPosition(view);
final int column = position % mSpanCount;
final int parentWidth = parent.getWidth();
int spacing = (int) (parentWidth - (mItemSize * mSpanCount)) / (mSpanCount + 1);
outRect.left = spacing - column * spacing / mSpanCount;
outRect.right = (column + 1) * spacing / mSpanCount;
if (position < mSpanCount) {
outRect.top = spacing;
}
outRect.bottom = spacing;
}
}
recyclerview_item.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/recycler_view_item_width"
...
>
...
</LinearLayout>
dimens.xml
<dimen name="recycler_view_item_width">60dp</dimen>
活动
int numberOfColumns = 3;
mRecyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
mRecyclerView.setAdapter(...);
mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(3,
getResources().getDimensionPixelSize(R.dimen.recycler_view_item_width)));
RecyclerViews支持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.getChildLayoutPosition(view) == 0) {
outRect.top = space;
} else {
outRect.top = 0;
}
}
}
然后通过
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing);
mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels));
如果你想要物品周围的间距和物品大小相等,下面是一步一步的简单解决方案。
ItemOffsetDecoration
public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
private int mItemOffset;
public ItemOffsetDecoration(int itemOffset) {
mItemOffset = itemOffset;
}
public ItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId) {
this(context.getResources().getDimensionPixelSize(itemOffsetId));
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(mItemOffset, mItemOffset, mItemOffset, mItemOffset);
}
}
实现
在源代码中,将ItemOffsetDecoration添加到RecyclerView中。 项偏移值应该是实际值的一半大小,作为项之间的空间。
mRecyclerView.setLayoutManager(new GridLayoutManager(context, NUM_COLUMNS);
ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(context, R.dimen.item_offset);
mRecyclerView.addItemDecoration(itemDecoration);
同样,设置项目偏移值为itsRecyclerView的填充,并指定android:clipToPadding=false。
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="@dimen/item_offset"/>
推荐文章
- Android选择器和文本颜色
- 视图绑定-我如何获得包含布局的绑定?
- 在Android Studio中改变矢量资产的填充颜色
- 在构建中编写注释的语法是什么?gradle文件?
- 如何以编程方式添加按钮色调
- 用Android Studio进行调试永远停留在“等待调试器”状态
- Openssl不被视为内部或外部命令
- 无法执行dex:在Eclipse中超过GC开销限制
- 如何以编程方式将视图添加到视图
- 单击url会打开默认浏览器
- 使用Retrofit刷新OAuth令牌,而不修改所有调用
- 多个dex文件定义了landoid /support/v4/accessibilityservice/AccessibilityServiceInfoCompat
- 如何获得动作栏的高度?
- 从活动外部调用startActivity() ?
- createScaledBitmap的过滤器参数做什么?