瀑布流布局切Tab跳跃问题原因及两种解决方案

简介: 瀑布流布局切Tab跳跃问题原因及两种解决方案

1. 问题描述



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


image.png


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


2. 问题分析


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



image.png

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


image.png


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

image.png

2.4 StaggeredGridLayoutManager#getMaxEnd方法中

image.png

2.5 StaggeredGridLayoutManager#Span#getEndLine方法中

image.png

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


2.6 StaggeredGridLayoutManager#Span#invalidateCache方法中

image.png

2.7 找寻invalidateCache方法被谁调用了

image.png

2.8 StaggeredGridLayoutManager#Span#clear方法中

image.png

2.9 找寻clear方法被谁调用了

image.png

2.10 StaggeredGridLayoutManager#onDetachedFromWindow方法如下

image.png

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


image.png

image.png

image.png

3. 解决方案


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

image.png

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


image.png

最后效果如下

image.png

相关文章
|
5月前
【奇技淫巧】实现flex布局中,单独某个元素挪到右侧、底部,与其他元素排列不同,就像是个另类。(主要是用到margin-left和align-self)
【奇技淫巧】实现flex布局中,单独某个元素挪到右侧、底部,与其他元素排列不同,就像是个另类。(主要是用到margin-left和align-self)
|
2月前
|
前端开发
导航新风尚:CSS梯形设计,让网站菜单不再单调!
导航新风尚:CSS梯形设计,让网站菜单不再单调!
|
4月前
|
前端开发
css元素实现垂直竖直万能居中
css元素实现垂直竖直万能居中
29 0
|
9天前
|
前端开发 容器
前端基础(十五)_多栏布局(两列自适应布局、圣杯布局---三列布局、双飞翼布局--三列布局、等高布局)
本文介绍了前端开发中的多种自适应布局技术,包括两列自适应布局、圣杯布局(三列布局)、双飞翼布局(三列布局)和等高布局。文章通过代码示例展示了如何使用HTML和CSS实现这些布局,以及如何通过flex布局简化实现过程。
33 2
|
5月前
|
小程序 前端开发 Android开发
微信小程序(van-tabs) 去除横向滚动条样式(附加源码解决方案+报错图)
微信小程序(van-tabs) 去除横向滚动条样式(附加源码解决方案+报错图)
279 1
|
5月前
|
小程序
微信小程序scroll-view横向滚动和纵向滚动实现(亲测管用)
微信小程序scroll-view横向滚动和纵向滚动实现(亲测管用)
|
5月前
|
前端开发 容器
如何实现一个两栏布局,右侧自适应?三栏布局中间自适应?
要实现一个两栏布局,右侧自适应的效果,可以使用 CSS 的 Flexbox 或 Grid 布局来实现。以下是使用 Flexbox 实现的示例:
64 1
|
12月前
|
UED 容器
如何实现侧边两栏宽度固定,中间栏宽度自适应的布局?——双飞翼布局、圣杯(Holy Grails)布局
如何实现侧边两栏宽度固定,中间栏宽度自适应的布局?——双飞翼布局、圣杯(Holy Grails)布局
75 0
【项目经验】elementui抽屉(从下到上方向)实现向上拉伸
elementui抽屉二次封装(可以向上拉伸)改变抽屉高度
164 0
|
iOS开发
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)
134 0
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)