如何使用GridLayoutManager与RecyclerView设置列间距? 在我的布局中设置空白/填充没有效果。
当前回答
class VerticalGridSpacingDecoration(private val spacing: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: State
) {
val layoutManager = parent.layoutManager as? GridLayoutManager
if (layoutManager == null || layoutManager.orientation != VERTICAL) {
return super.getItemOffsets(outRect, view, parent, state)
}
val spanCount = layoutManager.spanCount
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
with(outRect) {
left = if (column == 0) 0 else spacing / 2
right = if (column == spanCount.dec()) 0 else spacing / 2
top = if (position < spanCount) 0 else spacing
}
}
}
其他回答
只有一个简单的解决方案,您可以记住并在任何需要的地方实施。没有bug,没有疯狂的计算。在卡片/物品布局中放置空白,并在RecyclerView中放置相同大小的填充:
item_layout.xml
<CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:margin="10dp">
activity_layout.xml
<RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"/>
更新:
这个问题的答案似乎比他们应该做的要复杂。以下是我的看法。
假设您希望网格项之间有1dp的间距。做以下几点:
为每个项目添加0.5dp的填充 给RecycleView添加-0.5dp的填充 就是这样!:)
class VerticalGridSpacingDecoration(private val spacing: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: State
) {
val layoutManager = parent.layoutManager as? GridLayoutManager
if (layoutManager == null || layoutManager.orientation != VERTICAL) {
return super.getItemOffsets(outRect, view, parent, state)
}
val spanCount = layoutManager.spanCount
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
with(outRect) {
left = if (column == 0) 0 else spacing / 2
right = if (column == spanCount.dec()) 0 else spacing / 2
top = if (position < spanCount) 0 else spacing
}
}
}
下面的代码将处理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;
}
}
然后使用它
mRecyclerView.addItemDecoration(new SpacesItemDecoration(mMargin));
这就是最后对我有用的方法:
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,但我不相信有。
推荐文章
- 警告: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文件