如何使用GridLayoutManager与RecyclerView设置列间距? 在我的布局中设置空白/填充没有效果。
当前回答
感谢edwardaa的回答https://stackoverflow.com/a/30701422/2227031
另一点需要注意的是:
如果total spacing和total itemWidth不等于屏幕宽度,您还需要调整itemWidth,例如,在适配器onBindViewHolder方法
Utils.init(_mActivity);
int width = 0;
if (includeEdge) {
width = ScreenUtils.getScreenWidth() - spacing * (spanCount + 1);
} else {
width = ScreenUtils.getScreenWidth() - spacing * (spanCount - 1);
}
int itemWidth = width / spanCount;
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) holder.imageViewAvatar.getLayoutParams();
// suppose the width and height are the same
layoutParams.width = itemWidth;
layoutParams.height = itemWidth;
holder.imageViewAvatar.setLayoutParams(layoutParams);
其他回答
对于这个问题,有一个非常简单而灵活的解决方案,它只使用适用于每个LayoutManager的XML。
假设你想要一个相等的X间距(例如8dp)。
在另一个布局中包装CardView项 给外层布局填充X/2 (4dp) 使外层布局背景透明
...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@android:color/transparent"
android:padding="4dip">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.CardView>
</LinearLayout>
给你的RecyclerView填充X/2 (4dp)
...
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp" />
就是这样。你有完美的X (8dp)间距。
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
}
}
}
这也适用于RecyclerView with header。
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
private int headerNum;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge, int headerNum) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
this.headerNum = headerNum;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view) - headerNum; // item position
if (position >= 0) {
int column = position % spanCount; // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // top edge
outRect.top = spacing;
}
outRect.bottom = spacing; // item bottom
} else {
outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing; // item top
}
}
} else {
outRect.left = 0;
outRect.right = 0;
outRect.top = 0;
outRect.bottom = 0;
}
}
}
}
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));
如果你已经滚动到这个答案,我写了一个等间距库,支持垂直/水平,LTR/RTL,线性布局/GridLayout管理器和边缘包含。它基本上是一个文件,所以你可以复制粘贴该文件到你的代码中。
我试图支持StaggeredGridLayout,但这个布局返回的跨度索引不可靠。我很乐意听到任何有关这方面的建议。
推荐文章
- 警告: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文件