在android应用中,要实现一个Recycleview,使用GridLayoutManager格子排列,且排列成4列
实现水平方向间距均等(没有外边距)。

(均分为3列5列等、竖直方向、有边距等原理相同。)

先看最终效果图。

---
xml中这样配置

<androidx.recyclerview.widget.RecyclerViewandroid:background="#bbffbb"android:layout_width="match_parent"android:layout_height="wrap_content"app:spanCount="4"tools:listitem="@layout/layout_item"/>

为了醒目,我们让RecyclerView背景是浅绿色。

每一个item的配置如layout_item.xml所示

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="wrap_content"android:background="#ffcccc"android:layout_height="wrap_content"><TextViewandroid:id="@+id/name"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:gravity="center"android:textSize="12sp"app:layout_constraintEnd_toEndOf="@+id/thumb"app:layout_constraintStart_toStartOf="@+id/thumb"app:layout_constraintTop_toBottomOf="@+id/thumb"tools:text='NAME' /><com.google.android.material.imageview.ShapeableImageViewandroid:id="@+id/thumb"android:layout_width="65dp"android:layout_height="65dp"android:scaleType="fitXY"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"tools:background="@drawable/item_bg" /></androidx.constraintlayout.widget.ConstraintLayout>

为了醒目,我们让每一个item的背景色为浅红色。

Activity中,我们这样设置

class MyItemDecorator:RecyclerView.ItemDecoration(){val spanCount = 4override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {val position = parent.getChildAdapterPosition(view)val column =position% spanCount //第几列}
}binding.recycleHot.addItemDecoration(MyItemDecorator())

这样的显示效果,就是,最左边item的左边距离0,最右边item的右边距离不是0。

如果layout_item.xml里root布局

 android:layout_width="match_parent"

显示效果为:

---

在函数

getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State)


    view.width始终是0,不管item的root布局layout_widht是match_parent还是wrap_content。

---
终极解法 ,

我们设每个item的左右边距分别是L0、R0、L1、R1、L2、R2、L3、R3。

我们要求边距相同,即

R0+L1 =  R1+L2 = R2+L3 = space(间距)

每一个item占的地方是一样的,即

L0+item内宽度+R0 = item外宽度

L1+item内宽度+R1 = item外宽度

L2+item内宽度+R2 = item外宽度

L3+item内宽度+R3 = item外宽度

L0+R0 = L1+R1 = L2+R2 = L3+R3 = item外宽度-item内宽度          (设为p)

我们知道L0==R3==0
故可以推算出

L0 = 0
R0 = p-L0= p
L1 = space - R0 = space-p
R1 = p-L1 = p-(space-p) =  p*2 -space
L2 = space -R1 = sapce - (p*2-space) = space*2 - p*2(根据对称==R1==p*2-space)
R2 = p-L2 = p-(space*2-p*2) = p*3 - space*2(根据对称==L1==space-p)
L3 = space-R2 = space-(p*3-space*2) = space*3 -p*3(根据对称==R0==p)
R3 = 0

据此,

改善代码

 class MyItemDecorator : RecyclerView.ItemDecoration() {val spanCount = 4override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {val position = parent.getChildAdapterPosition(view)val column = position % spanCountfun dp2px(dp: Int): Int {val scale = view.resources.displayMetrics.densityreturn (dp * scale + 0.5f).toInt()}val itemWidth = parent.width / 4  //item外宽度val itemWidthInside = dp2px(65) //item内宽度val padding = itemWidth - itemWidthInside // pval space = (parent.width - 4 * itemWidthInside) / 3 // spaceif (column == 0) {outRect.left = 0outRect.right = padding} else if (column == 1) {outRect.left = space - (padding)outRect.right = padding * 2 - space} else if (column == 2) {outRect.left = space * 2 - padding * 2outRect.right = padding * 3 - space * 2} else if (column == 3) {outRect.left = paddingoutRect.right = 0}}}

layout_item.xml也要改,把root组件的layout_width固定。

android:layout_width="65dp"

这样就能实现GridLayoutManager是4列排布,各个item间距相同,最左边和最右边的item距离边框距离为0的效果。

如果RecycleView里设置了padding,比如

```<androidx.recyclerview.widget.RecyclerViewandroid:background="#bbffbb"
+               android:paddingHorizontal="16dp"android:layout_width="match_parent"android:layout_height="wrap_content"app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"app:spanCount="4"tools:listitem="@layout/layout_item"/>

此时,应该在Activity中,要把parent.Width改为parent.Width - parent.paddingLeft -parent.paddingRight

   override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {val position = parent.getChildAdapterPosition(view)val column = position % spanCountfun dp2px(dp: Int): Int {val scale = view.resources.displayMetrics.densityreturn (dp * scale + 0.5f).toInt()}val parentWidth = parent.width - parent.paddingLeft - parent.paddingRightval itemWidth = parentWidth / 4val itemWidthInside = dp2px(65)val padding = itemWidth - itemWidthInsideval space = (parentWidth - 4 * itemWidthInside) / 3when (column) {0 -> {outRect.left = 0outRect.right = padding}1 -> {outRect.left = space - (padding)outRect.right = padding * 2 - space}2 -> {outRect.left = space * 2 - padding * 2outRect.right = padding * 3 - space * 2}3 -> {outRect.left = paddingoutRect.right = 0}}}

效果为

RecyclerView使用GridLayoutManager 设置间距一致大小相关推荐

  1. gridlayoutmanager 设置间距_不设置主灯的客厅应当如何保证较好的灯光分布?

    如果没有从事照明设计的专业人士或者是比较有经验的室内设计师协助业主做决策,个人不太建议普通业主自行设置"无主灯客厅"的灯光分布. 在日常设计工作中,如果委托人确已考虑放弃主灯,通常 ...

  2. Android宫格动态列数,设置recyclerView的GridLayoutManager宫格间距

    遇到的问题 最近项目中用到了宫格列表布局,一直是用recyclerview作为列表开发控件,自然而然会用到其中的一个属性gridLayoutManager来做宫格布局列表.设计图是两行,并且是左右中都 ...

  3. Android RecyclerView使用GridLayoutManager间距设置

    使用RecyclerView设置间距,需要重写RecyclerView.ItemDecoration这个类.有如下的效果图需要实现,间距只有中间的格子和底部的格式之间有. Paste_Image.pn ...

  4. android n等分 layout,RecyclerView GridLayoutManager 等分间距

    RecyclerView 表格实现 RecyclerView 配合GridLayoutManager 可以实现类似表格的样式,为了实现均分,adapter 的布局宽度改为匹配父元素,即 android ...

  5. android网格布局间隙,RecyclerView网格布局瀑布流布局设置间距

    RecyclerView在网格布局或者瀑布流布局下,如果要设置间距,可以使用ItemDecoration. 下面的代码是设置显示两列数据RecyclerView的情况. cat.png @Overri ...

  6. Ubuntu 20.04 Desktop 设置桌面图标大小、间距

    Ubuntu 20.04 Desktop 设置桌面图标大小.间距 说明 正文 说明 时间:2020-12-24 本文基本完全抄袭了这篇文章:https://blog.csdn.net/weixin_3 ...

  7. UICollectionViewCell的设置间距

    UICollectionViewCell的设置间距 #pragma mark - UICollectionView 大小(宽高,平均一行三个) - (CGSize)collectionView:(UI ...

  8. ViewPager(六)让ViewPager用起来更顺滑——设置间距与添加转场动画

    用法概述: 1.换页监听与换页方法 2.懒加载及预加载定制 3.设置间距与添加转场动画 4.轮播.禁止滑动与指示器的配合 这篇和下一篇都是偏向技巧的东西,对于前端开发者来讲,开发的应用是直接面对用户的 ...

  9. html怎么设置一个表格的宽度一样吗,html表格单元格大小 怎样在html中设置所有表格大小一样...

    在html中怎样控制表格的宽度 表格的宽度设置都知道: .. 宽度虽然是这样设置的,但是的内容如果超出就还是可能会改变table的宽度, 这样就有两种情况,如果你不想改变宽且也不想改变行高,可是设置: ...

最新文章

  1. linux修改mysql密码sa_如何修改SA口令,数据库SA密码怎么改?
  2. Flutter开发之数据存储-2-文件存储(33)
  3. 获取当天时间的开始和结束 00:00:00和23:59:59
  4. ZOJ 3827 Information Entropy(数学题 牡丹江现场赛)
  5. caffe的python接口学习(8):caffemodel中的参数及特征的抽取
  6. SAP Spartacus的CMSPageGuard
  7. 了解OPhone平台---OPhone平台架构和主要开发组件
  8. 【2016年第6期】情境大数据建模及其在用户行为预测中的应用
  9. 【软考高项】信息系统项目管理师 论文写作技巧分享 (上)
  10. LMS Virtual Lab 流固模态分析
  11. matlab tf-idf,java 兑现tfidf
  12. Java之收集很好的Java学习资料地址+博客
  13. MySQL中SELECT语句简单使用 1
  14. 请勿在计算机室吃带果壳的食品英语,双语者如何在两种语言间切换?
  15. Opengl_19_assimp_1
  16. SpringMVC返回JSON格式数据
  17. 【雷达与对抗】【2014】MIMO雷达中的波束形成研究
  18. 在linux上使用spi-lcd屏 ST7735
  19. pythonmsgbox怎么使用_详解MessageBox(),MsgBox函数的正确使用
  20. Ubuntu系统显示实时网速信息

热门文章

  1. WordPress网站为什么及如何使用CDN加速访问
  2. 如何:创建 MDI 父窗体、子窗体、确定活动的 MDI 子窗体
  3. 深度学习框架智能时代的操作系统是什么?
  4. cesium底图切换
  5. opencv-之图像细化(直线细化)
  6. 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。例如, 罗马数字 2 写做 II ,即为两个并列的 1
  7. 有限状态机(FSM)的深入理解
  8. OS1和OS2单模光纤的区别
  9. 位运算——左移右移运算详解
  10. 值得我们思考的5个问题