如何使用GridLayoutManager与RecyclerView设置列间距? 在我的布局中设置空白/填充没有效果。
当前回答
如果你想要物品周围的间距和物品大小相等,下面是一步一步的简单解决方案。
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"/>
其他回答
这就是最后对我有用的方法:
binding.rows.addItemDecoration(object: RecyclerView.ItemDecoration() {
val px = resources.getDimensionPixelSize(R.dimen.grid_spacing)
val spanCount = 2
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val index = parent.getChildLayoutPosition(view)
val isLeft = (index % spanCount == 0)
outRect.set(
if (isLeft) px else px/2,
0,
if (isLeft) px/2 else px,
px
)
}
})
因为我只有2列(val spanCount = 2),我可以只做isLeft。如果有> 2列,那么我也需要一个isMiddle,两边的值都是px/2。
我希望有一种方法来获得应用程序:spanCount从直接从RecyclerView,但我不相信有。
为了使https://stackoverflow.com/a/29905000/1649371(上面)解决方案工作,我必须修改以下方法(以及所有后续调用)
@SuppressWarnings("all")
protected int getItemSpanSize(RecyclerView parent, View view, int childIndex) {
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
if (mgr instanceof GridLayoutManager) {
return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanSize(childIndex);
} else if (mgr instanceof StaggeredGridLayoutManager) {
return ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).isFullSpan() ? spanCount : 1;
} else if (mgr instanceof LinearLayoutManager) {
return 1;
}
return -1;
}
@SuppressWarnings("all")
protected int getItemSpanIndex(RecyclerView parent, View view, int childIndex) {
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
if (mgr instanceof GridLayoutManager) {
return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanIndex(childIndex, spanCount);
} else if (mgr instanceof StaggeredGridLayoutManager) {
return ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
} else if (mgr instanceof LinearLayoutManager) {
return 0;
}
return -1;
}
确保你在gradle模块中实现了这个:
implementation 'com.github.grzegorzojdana:SpacingItemDecoration:1.1.0'
创建这个简单的函数:
public static int dpToPx(Context c, int dp) {
Resources r = c.getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
最后实现如下所示的空格:
photosRecycler.addItemDecoration(new SpacingItemDecoration(2, dpToPx(this, 4), true));
上面的回答已经阐明了设置边缘处理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.removeItemDecoration(..)。如果不是这样,那么新的间隔计算将是不正确的。
就像这样:
recyclerView.removeItemDecoration(gridItemDecorator)
recyclerView.removeItemDecoration(listItemDecorator)
if (showAsList) {
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.addItemDecoration(listItemDecorator)
} else {
recyclerView.layoutManager = GridLayoutManager(this, spanCount)
recyclerView.addItemDecoration(gridItemDecorator)
}
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件