react native 瀑布流布局_记录瀑布流布局遇到的一个坑

开门见山,最近在做一个购物车+推荐商品功能。结合 RecyclerView StaggeredGridLayoutManager,完成瀑布流样式布局。完成之后,发现切换TAB,回到购物车页面后,页面会有些许的偏移。如下图。本来"洽洽香瓜子的价格 ¥9.90"紧贴TAB栏。再切换完TAB重新回来后,"洽洽香瓜子的价格 ¥9.90"字样竟然不见了。

99c477a2a16691549eba3f56d65cc76c.gif

发现此问题后,首先回滚到之前使用GridLayoutManager布局的代码。运行发现,GridLayoutManager并无此问题。看来问题的罪魁祸首是StaggeredGridLayoutManager。

问题分析如下:

购物车页面发生了偏移,那么必定调用了StaggeredGridLayoutManager的fill方法。

655fc89e69de735a4f8c21ca663c7e6b.png

fill方法会调用到layoutDecoratedWithMargins方法,给RV上的View布局

07de8d4f88061cde49da94ef68d917f5.png

layoutDecorateWithMargins中otherStart,start,otherEnd,end参数分别表示布局的left,top,right,bottom。既然发生了偏移,说明start,end参数发生了改变。start赋值处如下

StaggeredGridLayoutManager#fill方法中

641c527ab1850bb56bb56592a02b2d38.png

StaggeredGridLayoutManager#getMaxEnd方法中

6baa35f969f3d8ba6be9fb13b5be168d.png

StaggeredGridLayoutManager#Span#getEndLine方法中

c445ec126f7c60badae4d4665f87a852.png

会判断mCachedEnd 是否被置为无效。如果被置为无效那么会重新计算View的top位置。好像找到问题所在了。那么mCachedEnd在哪里被赋值成INVALID_LINE呢。找寻一番发现

StaggeredGridLayoutManager#Span#invalidateCache方法中

6cecc683bfa62cef1a9a84790ff8b6d0.png

找寻invalidateCache方法被谁调用了

aa9042c41a444b7ba549579aacf157ae.pngStaggeredGridLayoutManager#Span#clear方法中

c69b73291d506e16a080ee8ba1ae4651.png

找寻clear方法被谁调用了

27c7e33f9edba73e3e47a4ced7c6d8c2.png

StaggeredGridLayoutManager#onDetachedFromWindow方法如下

0ca14b3a2c7ca63380e5849760284167.png

由此可见,切换TAB的时候触发了View的onDetachedFromWindow方法,从而清空了StaggeredGridLayoutManager中所有布局的基准线,EndLine。重新返回购物车界面,会将当前RecyclerView中的可见的第一项View从0开始重新布局,导致了偏移。由于GridLayoutManager没有发现偏移。我们可以对比一下他们的onDetachedFromWindow方法实现。

bd4571418ebd3217f088296443da565c.png

f6d7f791eb65e4f43b8153b239f6e928.png

那么解决方案来了。

解决方案一:重写StaggeredGridLayoutManager的onDetached。nothing to do

e5b074eea15d5e1f523fbfc32d028cea.png

解决方案二:使用StaggeredGridLayoutManager的SavedState。由代码可见,SavedState会保存瀑布流布局的参数。那么我们可以在onDetachedFromWindow被调用之前调用onSaveInstanceState方法,在onAttachedToWindow中调用

04f55809615d35784e9ca6402d11c7b9.png

解决方案二如下

db3c6f2852b53467146427dd07c874b8.png

最后效果如下

c837b61f5d3aa06898039b7674d55212.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值