如何自定义RecycleView item的间距
引言
在以前使用ListView和GridView时,设置item之间的间距还是相对比较简单的,因为它们的基本属性里面Android已经定义好了,可以直接设置属性值即可。但Google为了通用性和灵活性(至少我是这么认为-.-),对于V7包中的RecycleView来说,则需要自己实现ItemDecoration类的getItemOffsets(Rect outRect, View view,... ...)抽象方法。
局限
下面的推理只限于VERTICAL情况,至于HORIZONTAL情况的考虑方式应该是类似,大家就自行去考虑把,嘿嘿o(∩_∩)o
推理
嗯,接下来就是根据不同的布局情况找到item的outRect的计算规律(outRect负责存储item之间间距)。
首先对于RecycleView的LayoutManager为LinearLayoutManager,或者为GridLayoutManager但spanCount为1的情况先忽略,因为太简单了=。= 。
我们接下的考虑重点是当RecycleView的LayoutManager为GridLayoutManager且spanCount大于1的情况(暂且默认每个Item的spanSize的大小都为1,后面为具体讨论)。
其实仔细观察后你会发现,outRect的top和bottom计算远比right和left简单的多,因为在VERTICAL情况下,高度是没有限制的,所以我们计算时需要保证只对第一行的item的outRect.top赋值,对每个item的outRect.bottom都赋值即可,这样就可以保证每行item都在统一水平线上且垂直相隔的距离都是相等的。主要代码如下:
// set top to all in first lane
if (position < mCountInFirstLine) {
outRect.top = mSpace;
}
outRect.bottom = mSpace;
对于outRect的right和left的计算,首先要明确的是三个已知条件,分别如下:
假设每个item间的左右间距为D(D>=0,常量),一共有n个item(1,2,3,... ... n),第i个item的左间隔距离为 \(x_{i}\),右间隔距离为\(y_{i}\) (1<=i<=n,i为自然数) 。
$ x_{i}+ y_{i}=d (1<=i<=n,i为自然数,d为未知正数)$
\(y_{i}+x_{i+1}=D(1<i<=n)\)
\(x_{1}=D, y_{1}=D\)
其中需要说明的是,由于每个item的原始宽度一致,要使得每个item的左右边距在空出相应距离后仍宽度一致,则公式1一定成立,具体示意图如下:
由图可知,自然的我们可以很快的找到一个等式①,即:
\]
而由公式1可知:$$x_{i}+ y_{i}=d,即y_{i}=d-x_{i}$$
所以等式①为:$$nd=(n+1)D,即d=D+D/n$$
这就是d的计算公式,当然到这里证明还没有结束,我们联合公式1和公式2可知:$$x_{i+1}-x_{i}+d=D,即x_{i+1}-x_{i}=-D/n(其中0<i<n,n>=1)$$
显然这是一个标准的等差数列,同时由公式3可知:\(x_{1}=D\),则第i个item的左间隔距离计算公式为:$$x_{i}=D-D/ni(其中0<i<=n,n>=1)$$再由公式1和等式①即可推得$$y_{i}=D/n+D/ni(其中0<i<=n,n>=1)$$至此关于item的左右间隔距离的计算公式基本证明结束。
进一步推理
当然上述的推理结果是默认每个Item的spanSize的大小都为1为前提条件进行的,所以为了公式更加通用,下面我们具体讨论当spanSize大小不固定的情况。
首先需要明确的是spanSize的大小并不影响item的outRect.top和outRect.bottom的计算(原因可自行脑补=.=)。
而当每个item的spansize大小不一样时,关于item的outRect.left和outRect.right的计算其实和spanSize=1的情况是基本一样的,我们只需要换个思维方式,即一个spanSize=N的item可以看作是N个spanSize=1的item,其中N>0,且N为自然数,$$item_{spanSize=N}的x=x_{1}$$$$item_{spanSize=N}的y=y_{N}$$
具体公式如下:$$x_{i}=D-D/nai(其中0<ai<=n,n>=1)$$ $$y_{i}=D/n+D/n(ai+item_{i的spanSize}-1)(其中0<ai<=n,n>=1)$$
其中需要注意的是ai表示的该item在一行中的实际位置,即若第一个\(item_{spanSize=2}\)的ai=1时,第二个\(item\)的ai=3。
OK,至此公式的推理全部结束,有关示例源码下载连接。
题外
唉,当初理清这些关系真的是花了好久(主要是好久不做数学题,生疏了-。-),希望能给大家提供些帮助,当然若有不足的地方欢迎指正。
这是搬到上海来写的第一篇文章,真的是“憋”了好久(─.─)|||,以后得更加勤快些,不能颓废下来。
作者:XycZero
查看原文:http://www.xyczero.com/blog/article/23/.
如何自定义RecycleView item的间距的更多相关文章
- 使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
AsyncTask使用方法详情:http://www.cnblogs.com/zzw1994/p/4959949.html 下拉开源框架PullToRefresh使用方法和下载详情:http://ww ...
- iOS11UINavigationBar的item左右间距调整
相信很多同学都知道在iOS7之后调整导航栏两侧按钮距离左右间距,其实就是在左右barButtonItem的数组中添加一个宽度为负的占位item. - (void)addLeftBarButtonIte ...
- Android 自定义TextView 实现文本间距
Android系统中TextView默认显示中文时会比较紧凑,不是很美观.为了让每行保持一定的行间距,可以设置属性android:lineSpacingExtra或android:lineSpacin ...
- NGUI 自定义 Drag Item Script
最近要实现一个NGUI效果. 查看了一下,NGUI有个自带 UIDragDropItem.cs 的组件进过修改后即可以实现. 下面贴上UI布局,代码: mDragDropItem.cs using U ...
- Typora 自定义主题 修改左右间距
打开偏好设置,打开主题文件夹 比如要修改night主题中的间距,编辑night.css文件,修改#write样式即可. 修改其他样式类试.
- Android 自定义ListView Item侧滑删除
本程序是基于网上开源项目修改而来,具体来源忘了,懒得搜了,如果有不合适的地方,请原作者联系我,我会及时回复和处理的! 该例子程序中主要包含两个ListView,一个是实现侧滑删除,一个是侧滑出菜单,代 ...
- Android ExpandableListView group的item有间距child间隔不变
<ExpandableListView android:id="@+id/lv" android:layout_width="fill_parent" a ...
- Android recycleview item水波纹效果
item的xml 根标签下添加如下三个属性 android:clickable="true" android:focusable="true" android: ...
- listview自定义背景以及item自定义背景
item向自定义背景,可以根据position来设置不同的背景. listview背景设置是需要注意设置下面这几项: //点下时整个页面的背景 android:cacheColorHint=" ...
随机推荐
- hdoj 1010 Tempter of the Bone【dfs查找能否在规定步数时从起点到达终点】【奇偶剪枝】
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- 使用JavaScript扫描端口
<html> <title>端口扫描</title> <head></head><form><label fo ...
- git 分支策略
转 http://www.ruanyifeng.com/blog/2012/07/git.html 作者: 阮一峰 如果你严肃对待编程,就必定会使用"版本管理系统"(Versio ...
- C# Timer执行方法
private void button3_Click(object sender, EventArgs e) { System.Timers.Timer t = new System.Timers.T ...
- 【Android - 框架】之Fresco的使用
当下有很多图片加载框架,常见的有Glide.Fresco.Picasso等.Glide因为其体积小.缓存机制强大等优点,受到了广大程序员的青睐:Fresco虽然体积比较大,缓存机制也没有Glide强大 ...
- WCF - 序列化
数据是信息的载体 在不同环境中有不同的类型 为保证处于不同平台的的应用能够正常的进行数据交互 必须采用一种双方都能理解的数据类型 XML无疑是最好的选择 但不是唯一的选择 例如JSON也是一种普遍认可 ...
- 前端高性能滚动 scroll 及页面渲染优化
前言 最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作.本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲 ...
- Android开发:最详细的 NavigationDrawer 开发实践总结
最详细的 NavigationDrawer 开发实践总结 继前面写的两篇文章之后(有问题欢迎反馈哦): Android开发:Translucent System Bar 的最佳实践 Android开发 ...
- xslt语法之---If Else
大家都知道,XSL中是没有if else的,那么要想实现if else该怎么办呢? 其实很简单 <xsl:choose> <xsl:when test="position( ...
- Dreamweaver cs6安装破解
Dreamweaver 是前端开发的必备软件.目前最新版本为CS6,与CS5相比多了对HTML5.CSS3.jquery的关联支持,可以更方便的在Dreamweaver中编写前端代码. 安装准备: 1 ...