Android Recyclerview间距 均分 完美布局 支持任意列数和两端间距

Android实现空间不够,自动换行 阅读详情

最近项目中要在RecyclerView的Grid中均分间距,看了源码和一些文章,下面的这篇很有启发,在此引用一下,并且在他的基础上支持任意列数和两端间距。最后附上代码:

原文链接:https://blog.youkuaiyun.com/lovext4098477/article/details/80419201

简介:

  App中,用到最多的设计就是列表形式的布局,而RecyclerView的出现,也完完全全的替代了之前的Listview、GridView,成为android控件中,用途最为广泛的widget之一,今天就来简单介绍一下,RecyclerView的一些布局方法。

实战:

  我们经常在设计稿中看到各式各样的列表,最通常的需求,就是对各个item进行排列,这就运用到了对分割线的处理。在RecyclerView中,有一个public void addItemDecoration(RecyclerView.ItemDecoration decor)的方法,RecyclerView.ItemDecoration这个类里包含了一个getItemOffsets的方法,我们就是要通过这个方法去对每个item分割,通过设置不同的offset来改变间距。以下图这个相册的为例:

 

  让我们来简单地剖析一下布局,假设屏幕是720px,每个间距为20px,通过计算,每个item的长宽为165px。

  这时候,很多人会考虑这样去设置

  我这里是dp转px,720是2x,所以delta是10px,通过parent.getChildAdapterPosition(view)来判断是每一行的第几个,然后第一个item设置了左0右10,第二个左10右10,第三个10右10,第四个左10右0。嗯,理论上来看好像是这样的,动手试试。结果发现,这样的布局并没有到达上图设计的效果。这是为什么呢?

  首先,我们要了解RecyclerView的分割原理,当一个RecyclerView设置了一个GridLayoutManager(this,count),并且count为4的时候,实际上就是将屏幕均分为四份,每一份都是180px宽(以720px为例,我们只考虑左右,暂不考虑上下,原理是相同的),如果不设置ItemDecoration,那么默认item由左开始布置,也就是说,165px的View在它的布局中是这样婶儿的。

  显而易见,无论我如何设置,item距边界最多就15px(left+right),如果要保证第一个item和第二个item间距为20px,那么我只需要将第二个item设置一个left为5px就可以达到想要的效果。第三第四个也同理。

  所以正确的左右设置应该为

 

在此基础上进行改进,支持任意列数和两端间距:

核心代码:

RecyclerView.LayoutManager rvLayoutManager = parent.getLayoutManager();

        if (rvLayoutManager == null || parent.getAdapter() == null) {
            return;
        }
        if (gapHSizePx < 0 || gapVSizePx < 0) {

            DisplayMetrics displayMetrics = new DisplayMetrics();
            parent.getDisplay().getMetrics(displayMetrics);
            gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics);
            gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics);
            edgePaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, edgePaddingDp, displayMetrics);

            if (rvLayoutManager instanceof GridLayoutManager) {
                GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
                spanCount = layoutManager.getSpanCount();
                eachItemPaddingH = (edgePaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount;
            } else if (rvLayoutManager instanceof StaggeredGridLayoutManager) {
                StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) parent.getLayoutManager();
                spanCount = layoutManager.getSpanCount();
                eachItemPaddingH = (gapHSizePx * (spanCount - 1)) / spanCount;
                //特殊设置
                int rvPadding = 0;
                if (layoutManager.getOrientation() == StaggeredGridLayoutManager.VERTICAL) {
                    rvPadding = edgePaddingPx - gapHSizePx / 2;
                } else {
                    rvPadding = edgePaddingPx - gapVSizePx / 2;
                }
                rvPadding = rvPadding >= 0 ? rvPadding : 0;
                parent.setPadding(rvPadding, 0, rvPadding, 0);
            } else if (rvLayoutManager instanceof LinearLayoutManager) {
                spanCount = 1;
                eachItemPaddingH = (edgePaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount;
            } else {
                throw new RuntimeException("不支持的LayoutManager");
            }
        }

        int position = parent.getChildAdapterPosition(view);
        if (!handleDecorationAtAdapterPosition(outRect, view, parent, state, position)) {
            if (rvLayoutManager instanceof GridLayoutManager) {
                setGridDecoration(outRect, view, parent, state, position);
            } else if (rvLayoutManager instanceof StaggeredGridLayoutManager) {
                setStaggeredGridDecoration((StaggeredGridLayoutManager) rvLayoutManager, outRect, view, parent, state, position);
            } else if (rvLayoutManager instanceof LinearLayoutManager) {
                spanCount = 1;
                setLinearDecoration((LinearLayoutManager) rvLayoutManager, outRect, view, parent, state, position);
            } else {
                throw new RuntimeException("不支持的LayoutManager");
            }
        }
        if (BuildConfig.DEBUG) {
            Log.d("ItemDecoration", "pos=" + position + "," + outRect.toShortString());
        }

下载地址:GridAverageGapItemDecoration

另外如果项目中用到了Brvah,并且想自定义Section中的间距的话,看这篇:

BRVAH的Section中自定义间距,条目完美均分,支持Section顶部和底部间距

Android RecyclerView使用GridLayoutManager间距设置的方法 阅读详情

相关推荐

Android RecyclerView用法 视频列表 两列

Android RecyclerView滑动列表 ,可横向 纵向布局 。视频播放滑动列表 2列

Android自动换行的流式布局

我们在开发过程中经常会遇到列表item宽度不定的情况,当显示不下时需要自动换行,常见的例子如一些热门话题标签、搜索热词等展示,今天我们就梳理出几种常用自动换行的流式布局来解决。

Over_dose的博客 4552

单片机开发者的福音:3步搞定VSCode智能补全(IAR工程+Clangd实战)

本文为单片机开发者提供了一套高效解决方案,通过EIDE插件将IAR工程导入VSCode,并生成关键的compile_commands.json文件,结合Clangd配置,仅需三步即可实现精准的智能代码补全、一键跳转等现代编辑功能,大幅提升嵌入式开发效率。

coffee的博客 524

RecyclerView addItemDecoration 的妙用 - item 间距平均分布和添加分割线

前言 RecyclerView,在开发当中使用非常频繁的一个控件,今天,主要讲解以下两个问题 添加分割线 item 间距的平均分布 addItemDecoration 方法简介 我们先来看一下 addItemDecoration 方法 [官网链接](https://developer.android.com/reference/android/support/v7/widget/Recycl...

徐公,微信公众号同名 2万+

用HFSS复现经典论文:从零搭建带孔缝屏蔽箱体模型(附完整建模步骤与避坑指南)

本文详细介绍了如何使用HFSS电磁仿真软件复现经典论文中的带孔缝屏蔽箱体模型,包括从零搭建模型、设置激励与边界条件、求解优化及结果验证的全过程。特别提供了建模中的布尔运算陷阱、激励设置技巧等实操难点的避坑指南,帮助工程师和学生深入理解电磁屏蔽效能研究。

weixin_30530339的博客 159

【数据集】全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

WW、forever的博客 389

android 均匀布局,Android Recyclerview间距 均分 完美布局 支持任意列数和两端间距-Go语言中文社区...

最近项目中要在RecyclerView的Grid中均分间距,看了源码和一些文章,下面的这篇很有启发,在此引用一下,并且在他的基础上支持任意列数和两端间距。最后附上代码:简介:App中,用到最多的设计就是列表形式的布局,而RecyclerView的出现,也完完全全的替代了之前的Listview、GridView,成为android控件中,用途最为广泛的widget之一,今天就来简单介绍一下,Recy...

weixin_29082143的博客 1045

第十届MathorCup高校数学建模挑战赛-B题:养老服务床位需求预测与运营模式研究

当养老床位数增加时存在的商机,提出了相应的养老服务床位的运营商业模式。就业的可能性,建立多目标规划模型,尽可能同时满足三方面的要求。务床位的需求、制定合理的养老服务床位发展规划,是构建和谐社会、幸福社会。问题一的床位需求与市场类型的分类结果,查找关于国内养老院的相关数据,探。求,又能持续发展养老事业,同时还能促进社会就业的养老服务床位运营的商业。养老服务床位数的增加能够带来的就业方面因素的影响,并对这些因素进行一个。你们的模型及其结论为科学依据,对政府管理部门针对养老床位规划提出合理的。

getusushu的博客 1139

android布局平均,Android recyclerview 支持网格布局的间隙平均分割

GridSpacingItemDecorationpublic class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {private int spanCount;private int spacing;private boolean includeEdge;public GridSpacingItemDecorat...

weixin_35513543的博客 663

摆脱英文束缚!群晖Transmission4.0.4全新中文界面攻略

在群晖安装完官方Transmission4.0.4套件后,界面是英文状态的,不太好用。但是按照网上分享的原来4.0以前版本的方法更新UI又失败,所以自己搞了下成功了,分享给需要的朋友。

XiaoqiangClub的博客 5217

SDR 和 DDR 的区别

SDR 和 DDR 的差别,最明显提现在传输速率和频率上。DDR SDRAM与SDRAM的基本结构是相似的,最根本的区别在于DDR 支持在一个时钟周期内传输两次数据,,SDR 只能传输一次数据。

串起点滴 1961

基于HarmonyOS ArkTS API 24通过new PhotoItem(p)创建一个新的对象并替换数组中的原对象

在任何一个设计精良的应用中,色彩系统都是视觉一致性的基石。bg: string;这段代码定义了一个名为的接口,它包含了11个色彩字段,每个字段都对应应用界面中的一个特定功能角色。primary:主色调,通常用于页面头部、重要按钮等视觉重心区域。在本应用中,主色调选用了深棕色#3E2C23,既呼应了胶片暗房的氛围,又能提供足够的视觉对比度。brown:辅助棕色,用于次级强调元素,如标签背景、评分星星等,与主色调形成层次关系。bg:页面背景色,选用奶油色#F3EBDD。

2501_92985290的博客 952

AI上推荐 之 NeuralCF与PNN模型(改变特征交叉方式)

1. 前言 随着信息技术和互联网的发展, 我们已经步入了一个信息过载的时代,这个时代,无论是信息消费者还是信息生产者都遇到了很大的挑战: 信息消费者:如何从大量的信息中找到自己感兴趣的信息? 信息生产者:如何让自己生产的信息脱颖而出, 受到广大用户的关注? 为了解决这个矛盾, 推荐系统应时而生, 并飞速前进,在用户和信息之间架起了一道桥梁,一方面帮助用户发现对自己有价值的信息, 一方面让信息能够展现在对它感兴趣的用户前面。 推荐系统近几年有了深度学习的助推发展之势迅猛, 从前深度学习的传统推荐模型(协

Miracle8070 1万+

<android>RecyclerView使用GridLayoutManager间距均分等分问题,不要修改xml了太麻烦,一行代码适配所有

/** * recyclerview设置GridLayoutManager 等分margin时的自定义ItemDecoration */ public class RecyclerViewMarginDecoration extends RecyclerView.ItemDecoration { private int mMargin; int spanCount; public RecyclerViewMarginDecoration(Context context, int spanCoun..

csdn_lg_one的博客 4539

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

android 流布局(根据内容宽度自动换行的布局)

本文引用了http://blog.youkuaiyun.com/gesanri/article/details/48968803博客的代码,并在其基础上修改了一些不足之处。 主要体现在单个内容过多的情况,会出现过多的内容换行时换了多次(根内容行数有关),并且,设置了margin后太长的内容会在宽度上超出屏幕。 将修改好的代码分享如下: import java.util.ArrayList; i

4041

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

android 自动换行的线性布局

转载请注明出处:在项目中,有时候会有“横向排列,排满后自动换行”的需求(比如下图),要是子view是定长的就没什么好说的了,但如果是变长的话呢?这篇博客会帮你应对这种需求。 基本思路 最外层一层竖直线性布局(我们称为父布局) 新建水平线性布局(我们称为行布局) 计算待放入的view的宽度和行布局的剩下宽度 判断是否可以放入 (1). 若view的宽度小于等于剩余宽度,放入,到第三步; (2)

Jimi_Wu的专栏 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Recyclerview使用方法

package com.example.lianxi_recyclerview; public class Bean { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } package com.example.lianxi_recycler

李平的博客 2万+

RecyclerView中用GridLayoutManager时如何正确的设置内部控件的间距Margin

GridLayoutManager中如何正确的设置内部控件的间距margin1. 模拟情况2. 踩坑3. 正确用法4. 完整代码和使用例4.1 完整代码4.2 使用例参考材料 最下面有完整代码(仅ItemDecoration类)和使用例,可以直接跳过去查看。 1. 模拟情况 我们用RecyclerView,并采用GridLayoutManager,然后columns设置为3,表示一行有三个item。 item我就用一个带边框的矩形,里面放一个String,width和height都写成固定值50dp。 在什

wodongx123的博客 7687

RecyclerView使用GridLayoutManager 设置间距一致大小

在android应用中,要实现一个Recycleview,使用GridLayoutManager格子排列,且排列成4列 实现水平方向间距均等(没有外边距)。(均分为3列5列等、竖直方向、有边距等原理相同。)先看最终效果图。 --- xml中这样配置 为了醒目,我们让RecyclerView背景是浅绿色。 每一个item的配置如layout_item.xml所示 为了醒目,我们让每一个item的背景色为浅红色。 Activity中,我们这样设置 这样的显示效果,就是,最左边item的左边距离0,

coraline1991的专栏 1万+

不一样的RecyclerView优雅实现复杂列表布局(二)

前言学习了(一)中那个RecyclerView的一些基础知识,如果没有具体看懂可以再返回看不一样的RecyclerView优雅实现复杂列表布局(一),那么接下来我们就在(一)的基础之上,完善稍微复杂一点数据处理。不一样的RecyclerView优雅实现复杂列表布局(二)中使用的是GridLayoutManager模式,实现混合使用的效果: 1.首先加载的数据要有所改变,多种形式的数据加载,在Mai

向着太阳迎着光 5592

RecyclerView使用GridLayoutManager时如何等分间距

最近在做需求的时候,需要在界面展示一个四列的列表。毫无疑问,我们应该采用RecyclerView并采用它的网格布局管理器,即GridLayoutManager来实现。当然,这种实现肯定是没问题的。不过设计老师一般会要求让这几列的列表把给出的宽度等距离分割掉。也就是说,第一列和最后一列的列表不能距两边有间距,之间的需要等分间距。类似这样的效果 那么假如我们把宽度设置为wrap_content,则出来的效果距离右边还有相当距离,无法让最后一列内容紧贴右侧。假如我们将宽度设置为match_parent,再给

woaichihuoguoguo的博客 4568

RecyclerView GridLayoutManager列间距

GridLayout模式的时候,如果默认的列宽和比RecyclerView的容量小,那么就会每一列的右侧添加一个间距; 这个间距会导致RecyclerView整体向左偏移的一个效果; 要干掉这个偏移,大体可以通过以下3种手段: 算好RecyclerView的容量大小(即,去掉padding等之后的实际宽度),然后设置列宽的和正好等于这个宽度; 把第一列以外的列往右移; 把整体往右移,然后...

weixin_39821531的博客 7230

RecyclerView GridLayoutManager 等分间距

RecyclerView 表格实现 RecyclerView 配合GridLayoutManager 可以实现类似表格的样式,为了实现均分,adapter 的布局宽度改为匹配父元素,即 android:layout_width=“match_parent” 。 RecyclerView rvPhotoAlbums = findViewById(R.id.rv_photoAlbums_conten...

JM_beizi的专栏 1万+

AndroidRecyclerviewGridLayoutManager列间距 - Android Recyclerview GridLayoutManager column spacing

解决方案: RecyclerViews支持ItemDecoration的概念:特殊补偿和绘画在每个元素。见这个答案,您可以使用然后通过添加 原文: RecyclerViews support the concept of ItemDecoration: special offsets and drawing around each element. As seen in this a

yanggz888的专栏 3万+

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

遇到的问题最近项目中用到了宫格列表布局,一直是用recyclerview作为列表开发控件,自然而然会用到其中的一个属性gridLayoutManager来做宫格布局列表。设计图是两行,并且是左右中都有相同的间距,刚开始想到的是在xml设置间距就行了,出来的效果和设计图的大相径庭,所以这种方法不可行。后来无头绪在度娘一波乱找,了解到了recyclerview还有个addItemDecoration(...

weixin_29997523的博客 1104
上一篇: 并发之痛 Thread,Goroutine,Actor
下一篇: BRVAH的Section中自定义间距,条目完美均分,支持Section顶部和底部间距
candyguy242
博客等级 码龄17年 63粉丝 37原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值