IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> RecyclerView使用GridLayoutManager 设置间距一致大小 -> 正文阅读

[移动开发]RecyclerView使用GridLayoutManager 设置间距一致大小

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

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

先看最终效果图。


---
xml中这样配置

<androidx.recyclerview.widget.RecyclerView
? ? android: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">

? ? <TextView
? ? ? ? android: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.ShapeableImageView
? ? ? ? android: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 = 4
? ? override 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 = 4
? ? ? ? override fun getItemOffsets(
? ? ? ? ? ? outRect: Rect,
? ? ? ? ? ? view: View,
? ? ? ? ? ? parent: RecyclerView,
? ? ? ? ? ? state: RecyclerView.State
? ? ? ? ) {
? ? ? ? ? ? val position = parent.getChildAdapterPosition(view)
? ? ? ? ? ? val column = position % spanCount
? ? ? ? ? ? fun dp2px(dp: Int): Int {
? ? ? ? ? ? ? ? val scale = view.resources.displayMetrics.density
? ? ? ? ? ? ? ? return (dp * scale + 0.5f).toInt()
? ? ? ? ? ? }
? ? ? ? ? ? val itemWidth = parent.width / 4 ?//item外宽度
? ? ? ? ? ? val itemWidthInside = dp2px(65) //item内宽度
? ? ? ? ? ? val padding = itemWidth - itemWidthInside // p
? ? ? ? ? ? val space = (parent.width - 4 * itemWidthInside) / 3 // space
? ? ? ? ? ? if (column == 0) {
? ? ? ? ? ? ? ? outRect.left = 0
? ? ? ? ? ? ? ? outRect.right = padding
? ? ? ? ? ? } else if (column == 1) {
? ? ? ? ? ? ? ? outRect.left = space - (padding)
? ? ? ? ? ? ? ? outRect.right = padding * 2 - space
? ? ? ? ? ? } else if (column == 2) {
? ? ? ? ? ? ? ? outRect.left = space * 2 - padding * 2
? ? ? ? ? ? ? ? outRect.right = padding * 3 - space * 2
? ? ? ? ? ? } else if (column == 3) {
? ? ? ? ? ? ? ? outRect.left = padding
? ? ? ? ? ? ? ? outRect.right = 0
? ? ? ? ? ? }

? ? ? ? }
? ? }

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

android:layout_width="65dp"

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

?

如果RecycleView里设置了padding,比如

```
? ? ? ? ? ? <androidx.recyclerview.widget.RecyclerView
? ? ? ? ? ? ? ? android: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 % spanCount
? ? ? ? fun dp2px(dp: Int): Int {
? ? ? ? ? ? val scale = view.resources.displayMetrics.density
? ? ? ? ? ? return (dp * scale + 0.5f).toInt()
? ? ? ? }

? ? ? ? val parentWidth = parent.width - parent.paddingLeft - parent.paddingRight
? ? ? ? val itemWidth = parentWidth / 4
? ? ? ? val itemWidthInside = dp2px(65)
? ? ? ? val padding = itemWidth - itemWidthInside
? ? ? ? val space = (parentWidth - 4 * itemWidthInside) / 3
? ? ? ? when (column) {
? ? ? ? ? ? 0 -> {
? ? ? ? ? ? ? ? outRect.left = 0
? ? ? ? ? ? ? ? outRect.right = padding
? ? ? ? ? ? }
? ? ? ? ? ? 1 -> {
? ? ? ? ? ? ? ? outRect.left = space - (padding)
? ? ? ? ? ? ? ? outRect.right = padding * 2 - space
? ? ? ? ? ? }
? ? ? ? ? ? 2 -> {
? ? ? ? ? ? ? ? outRect.left = space * 2 - padding * 2
? ? ? ? ? ? ? ? outRect.right = padding * 3 - space * 2
? ? ? ? ? ? }
? ? ? ? ? ? 3 -> {
? ? ? ? ? ? ? ? outRect.left = padding
? ? ? ? ? ? ? ? outRect.right = 0
? ? ? ? ? ? }
? ? ? ? }
? ? }

效果为

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 17:00:33  更:2022-06-26 17:01:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:34:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码