RecyclerView GridLayoutManager 等分间距

2023-10-20 16:30

本文主要是介绍RecyclerView GridLayoutManager 等分间距,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • RecyclerView 表格实现
    • 添加间距 ItemDecoration
        • ItemDecoration 源码分析
        • 自定义ItemDecoration
        • 添加ItemDecoration
    • 等分间距
        • 实现思路
        • 最终实现

RecyclerView 表格实现

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

RecyclerView rvPhotoAlbums = findViewById(R.id.rv_photoAlbums_content);
rvPhotoAlbums.setLayoutManager(new GridLayoutManager(this, 4));
rvPhotoAlbums.setAdapter(new PhotoAlbumsAdapter());

效果图如下:

添加间距 ItemDecoration

ItemDecoration 源码分析

androidx.recyclerview.widget.RecyclerView#addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration)。
先简单看下 ItemDecoration 里的方法:

public abstract static class ItemDecoration {// ....省略其他方法介绍...../*** Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies* the number of pixels that the item view should be inset by, similar to padding or margin.* The default implementation sets the bounds of outRect to 0 and returns.* 解读:获取给定item view的偏移量,用outRect 表示。outRect的每个字段分别表示不同方向的偏移量,类似于填充或边距。* 默认设置为0,即没有间距。** <p>* If this ItemDecoration does not affect the positioning of item views, it should set* all four fields of <code>outRect</code> (left, top, right, bottom) to zero* before returning.* 如果不想影响item view 的位置,需要置outRect 的left, top, right, bottom 为0** <p>* If you need to access Adapter for additional data, you can call* {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the* View.** @param outRect Rect to receive the output.* @param view    The child view to decorate* @param parent  RecyclerView this ItemDecoration is decorating* @param state   The current state of RecyclerView.*/public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,@NonNull RecyclerView parent, @NonNull State state) {getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),parent);}
}

通过代码注释我们知道,可以通过继承 androidx.recyclerview.widget.RecyclerView.ItemDecoration 类处理间距。

自定义ItemDecoration
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {private int mSpanCount;//横条目数量private int mRowSpacing;//行间距private int mColumnSpacing;// 列间距/*** @param spanCount     列数* @param rowSpacing    行间距* @param columnSpacing 列间距*/public GridSpaceItemDecoration(int spanCount, int rowSpacing, int columnSpacing) {this.mSpanCount = spanCount;this.mRowSpacing = rowSpacing;this.mColumnSpacing = columnSpacing;}@Overridepublic void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。int column = position % mSpanCount; // view 所在的列// 列间距outRect.left = mColumnSpacing;// 如果position > 行数,说明不是在第一行,则不指定行高,其他行的上间距为 top=mRowSpacingif (position >= mSpanCount) {outRect.top = mRowSpacing; // item top}}
}
添加ItemDecoration
// 添加间距
rvPhotoAlbums.addItemDecoration(new GridSpaceItemDecoration(4,DpPxSpTool.INSTANCE.dip2px(this, 30),DpPxSpTool.INSTANCE.dip2px(this, 20)));

ok,我们看下效果:

(注:为了区分item view范围,我用不同的颜色描边来识别)
可以看出,item 整体偏右,这是因为GridLayoutManager 已经给item 划分了宽度,而我们在ItemDecoration 中给item view设置了左边距,所以会出现整体偏右,内容挤压的情况。

等分间距

实现思路

为了达到同等间距,我们需要同时设置item 的左右边距,并且使 左边view 的边距+ 右边view 的左边距 = 设置的列间距,从视觉效果上看起来是同等分间距。

先来梳理下等间距需要满足的条件:

  1. 各个模块的大小相等,即各列的left+right 值相等;
  2. 各列的间距相等,即前列的right + 后列的left = 列间距;

假设列间距为10,为了方便识别,我用字母代替所在列。
以2列为例:
在这里插入图片描述
检查条件1 :a.left +a.right = b.left+b.right = 5 结果:满足
检查条件2:a.right + b.left = 10 结果:满足

以3列为例:
在这里插入图片描述
检查条件1 :a.left +a.right = b.left+b.right = c.left+c.right ≈ 6.66 结果:满足
检查条件2:a.right + b.left = b.right + c.left ≈ 10 结果:满足

根据推演我们可以得出公式:
某列的left = 所在的列数 * (列间距 * (1 / 列数))
某列的right = 列间距 - 后列的left = 列间距 -(所在的列数+1) * (列间距 * (1 / 列数))
注:这里用的所在列数为从0开始

最终实现
/*** 描述 : RecyclerView GridLayoutManager 等间距。* <p>* 等间距需满足两个条件:* 1.各个模块的大小相等,即 各列的left+right 值相等;* 2.各列的间距相等,即 前列的right + 后列的left = 列间距;* <p>* 在{@link #getItemOffsets(Rect, View, RecyclerView, RecyclerView.State)} 中针对 outRect 的left 和right 满足这两个条件即可* <p>* 作者 : shiguotao* 版本 : V1* 创建时间 : 2020/3/19 4:54 PM*/
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {private final String TAG = "GridSpaceItemDecoration";private int mSpanCount;//横条目数量private int mRowSpacing;//行间距private int mColumnSpacing;// 列间距/*** @param spanCount     列数* @param rowSpacing    行间距* @param columnSpacing 列间距*/public GridSpaceItemDecoration(int spanCount, int rowSpacing, int columnSpacing) {this.mSpanCount = spanCount;this.mRowSpacing = rowSpacing;this.mColumnSpacing = columnSpacing;}@Overridepublic void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。int column = position % mSpanCount; // view 所在的列outRect.left = column * mColumnSpacing / mSpanCount; // column * (列间距 * (1f / 列数))outRect.right = mColumnSpacing - (column + 1) * mColumnSpacing / mSpanCount; // 列间距 - (column + 1) * (列间距 * (1f /列数))Log.e(TAG, "position:" + position+ "    columnIndex: " + column+ "    left,right ->" + outRect.left + "," + outRect.right);// 如果position > 行数,说明不是在第一行,则不指定行高,其他行的上间距为 top=mRowSpacingif (position >= mSpanCount) {outRect.top = mRowSpacing; // item top}}
}

效果:

打完,收工!

这篇关于RecyclerView GridLayoutManager 等分间距的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/248296

相关文章

什么是LED智能会议一体机?COB超微小间距LED会议一体机大势所趋

LED智能会议一体机,作为现代会议室革新的核心装备,正逐步颠覆传统会议模式的界限。它不仅仅是一台集成了高清显示、触控互动、音视频处理及远程协作等功能于一体的智能设备,更是推动会议效率与体验双重飞跃的关键力量。随着技术的不断进步,特别是COB(Chip On Board)超微小间距LED技术的引入,LED智能会议一体机正迎来前所未有的发展机遇,成为大势所趋。 COB技术通过将LED芯片直接封装在基

全倒装COB超微小间距LED显示屏的工艺技术,相比SMD小间距有何优势

全倒装COB(Chip On Board)超微小间距LED显示屏,在工艺技术上的革新,相较于传统的SMD(Surface Mount Device)小间距LED显示屏,展现出了多方面的显著优势。 首先,全倒装技术极大地提升了LED芯片的散热性能。通过将芯片直接焊接在基板上,减少了热阻,使得热量能够更快速地传导至基板并散发出去,有效避免了因高温导致的光衰和色彩偏移问题,从而保证了显示屏的长期稳定性

全倒装COBP1.5超微小间距LED显示屏快速抢占市场

随着全倒装COBP1.5超微小间距LED显示屏技术的日益成熟与成本的逐步降低,其市场渗透力愈发强劲,迅速在多个领域绽放出耀眼的光芒。不仅在传统的广告传媒、会议展览中成为不可或缺的视觉盛宴制造者,更在高端监控、虚拟现实体验、乃至医疗影像展示等前沿科技领域崭露头角。 随着市场需求的多样化,各大厂商纷纷加大研发投入,不断推出定制化解决方案,以满足不同场景下的特殊需求。这种灵活性与创新性,进一步推动了全

P0.7全倒装COB超微小间距LED显示屏厂家已量产,加速高清显示的发展

随着P0.7全倒装COB超微小间距LED显示屏技术的成功量产,这一里程碑式的成就不仅标志着高清显示技术迈入了全新纪元,更预示着未来视觉体验将迎来前所未有的变革。各大应用场景,如指挥中心、会议中心、大型活动直播、高端影院乃至家庭娱乐,都将因这项技术而焕发新生。 市场上,消费者对于视觉质量的追求日益高涨,P0.7全倒装COB显示屏以其极致细腻的画质、超高的色彩还原度以及卓越的稳定性,迅速成为行业新宠

全倒装P1.2COB技术推动超微小间距市场,已成为行业主流产品

随着全倒装P1.2 COB(Chip on Board)技术的不断成熟与广泛应用,超微小间距市场正以前所未有的速度蓬勃发展,不仅巩固了其作为行业主流产品的地位,更引领着显示技术迈向新的高度。这项技术通过直接将LED芯片封装在基板上,极大地提升了像素密度与发光效率,使得显示屏在保持高分辨率的同时,还能实现更广的视角、更高的对比度和更低的能耗,为用户带来前所未有的视觉盛宴。 在此背景下,各大厂商纷纷

RecyclerView的itemView的点击效果

1,需要在 itemView 的布局 根节点上添加  android:clickable="true" 2、或者通过代码实现 @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {  ((ViewHolder)viewHolder).textView

高质量的小间距LED显示屏有什么表现

随着企业对宣传和品牌形象提升的需求日益增长,LED显示屏凭借其立体化宣传和低成本优势,逐渐成为企业宣传的重要工具。近年来,小间距LED显示屏在市场上逐渐普及,生产厂家和产品种类也不断增加。面对如此众多的选择,许多人在选择时往往感到困惑。那么,什么样的小间距LED显示屏才算得上是高质量的呢? 1. 发光管的高质量 高质量的小间距LED显示屏首先表现为其发光管的卓越品质。优质的发光管具有稳

力扣刷题--164. 最大间距【简单】

题目描述🍗 给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1: 输入: nums = [3,6,9,1] 输出: 3 解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。 示例 2:

ScrollView嵌套RecyclerView再嵌套RecyclerView导致的布局展示不完整问题

背景:页面布局,最外层有个ScrollView,然后里面有个RecyclerView,然后每个RecyclerView的item都是一个RecyclerView 异常:页面展示不完整,最底下的Item 展示一半,在往上滑就滑不动了   解决: // 每一个item渲染完后重新计算外层recyclerview高度// 因为外层的recyclerview是先渲染的,渲染时 内部recyc

css spacing设置间距

word-spacing属性用于设置单词之间的间距。它只影响英文单词之间的间距,对中文无效。例如,设置word-spacing: 30px;将在每个单词之间增加30像素的间距。这个属性可以增加或减少字与字之间的空白,并且允许负值,即减少字与字之间的间距。 letter-spacing属性用于设置字母之间的间距,适用于中文和英文。例如,设置letter-spacing: 10px;将在每个字母之