Compose 滑动布局中嵌套的Grid网格布局

在这里插入图片描述
上面是需求图
整个布局是可以垂直方向滑动的,同时内部需要用垂直方向的网格布局来显示图片。并且通过让宽度或间距平分剩余空间,来实现对齐效果。如果丢个FlowRow代替Grid,是不能实现对齐的,基本会头重脚轻

同向可滑动嵌套的隐患

众所周知,同向的可滑动嵌套可能会导致性能问题。比如A布局允许垂直方向滑动,B是A布局中的一个RecyclerView,高度为wrapContent,由于B的父布局A可以垂直滑动,A对B的高度不做限制,B会一口气把所有的元素都加载出来,导致RecyclerView的延迟加载和回收逻辑都失效,如果数据太多的话会导致性能问题。如果是分页列表的话,那么它还会一直处于加载到底部-》触发加载下一页-》加载到底部的循环中,导致从性能问题进化到业务问题。

Compose中为了防止这个情况,对同向的滑动进行了限制,在大多数的同向可滑动布局嵌套时会直接抛出异常(除非child在对应方向上设置了具体的尺寸,比如B在A里面,B设置了Modifier.height(30.dp),这样可以正常运行)。

有一些场景,我们确定在特定的业务场景下,集合元素不会很多,而且UI就要求用高度自适应的网格布局来显示内容。在使用View时我们有很多方法,有直接的网格布局,也可以头硬上RecyclerView(虽然可能会导致问题,但View体系中并没有禁止开发者这么做,后果自负就是了)。
但是在Compose中,由于只提供了LazyXXXGrid,并没有那种不需要滑动,高度自适应,可以直接在滑动布局内部使用的Grid,有的时候会导致困扰——我不想把整个滑动界面改成LazyXXXGrid,我也确定Grid中的元素不会那么多,甚至只有几个,绝对不影响性能。
这个时候我们还只能自己实现一个简单的Grid了,直接上代码。

代码


import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
/**
 * 由于Compose只提供了懒加载的LazyVerticalGrid,又不允许同向的嵌套滑动,会直接抛出异常,所以需要我们自己实现Grid布局(很多时候我们知道嵌套滑动会导致懒加载失效,内容全部加载等问题,但是我们也确定一些使用场景里Grid的内容不会过多,就是想要使用Grid)。
 *
 * 用类似LazyVerticalGrid的布局效果:会在遵守[minItemSize]的前提下尽可能的在每一行放更多的项,并让他们平分剩余空间。
 *
 * 由于是简单实现,所以布局中的每一项会设置为正方形,高度向宽度对齐
 *
 * 比如总宽度为100,minItemSize为30,那么最终会有3列,每列宽度为100/3(这个例子中没有考虑[horizontalSpace])
 * @param minItemSize 子项的最小尺寸。在布局的最大宽度小于这个尺寸时,会让子项尺寸为最大宽度;否则子项的宽度至少为这个尺寸
 * @param horizontalSpace 水平方向的间距,只有一列时间距不会生效
 * @param verticalSpace 垂直方向的间距,只有一行时间距不会生效
 * @param content 直接往里丢内容即可,参考[Row],[Column]等布局的content参数
 */
@Composable
fun EasyGrid(
    minItemSize: Dp,
    modifier: Modifier = Modifier
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值