现在APP中使用RecyclerView加载瀑布流列表是一种很常见的布局操作,但是却有一个经常困扰我们的问题,就是瀑布流会闪烁和跳动,正好在近期的项目中我遇到并优化了这个问题,下面是解决思路,供大家借鉴
1:在初始化RecyclerView的时候,将 itemAnimator 设置为null,即不需要动画
binding.rvRecommend.apply {
itemAnimator = null
layoutManager = gridLayoutManager
adapter = newHomeAdapter
}
2:我们的瀑布流条目大概是这个样式:
A:图片的宽高接口并未返回,我们的需求是根据屏幕宽度来进行处理,因为要适配现在新出的折叠屏手机
B:最多两行的文案那里,只有一行的时候需要条目整体高度减小,即第一个文案和第二个文案中间的间距是固定的
单个条目布局:

条目.png
整体屏幕布局:

image.png
3:对条目的宽度进行计算:
A:这里的计算很简单,就是屏幕宽度-左中右间距的和,再除以2,就能得出条目的宽度
B:在viewholder中动态将宽度设置给条目中的最外层布局或者图片
C:由于我们的需求中图片的宽高是一样的,因此图片的高度也在这里设置
//计算条目宽度
val recoGoodsImgW = (ScreenUtils.getScreenWidth(mContext) - SizeUtils.getDimen(R.dimen.dp_30)) / 2
//动态设置宽高的代码示例
val p = binding.ivCommodityImg.layoutParams
p.width = recoGoodsImgW
p.height = recoGoodsImgW
binding.ivCommodityImg.layoutParams = p
4:通过上面的设置,加载瀑布流的时候基本就不会闪烁了,其中最主要的是 itemAnimator = null 这行代码,第三条的动态计算宽度其实主要是解决瀑布流左中右间距容易不一致的问题,当然宽高动态设置也能对闪烁问题起到一定的作用
5:做完上面的这些之后,产品又增加了 “删除条目的时候瀑布流要有一个补位动画” 的需求,其实这个补位动画就是 itemAnimator ,解决方案就是在进行删除之前,给RecyclerView设置动画,在用户进行下拉刷新和上拉加载更多的操作的时候,再将 itemAnimator 设置为null
binding.rvRecommend.itemAnimator = DefaultItemAnimator() //添加动画