瀑布流布局切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

相关文章
|
8月前
【奇技淫巧】实现flex布局中,单独某个元素挪到右侧、底部,与其他元素排列不同,就像是个另类。(主要是用到margin-left和align-self)
【奇技淫巧】实现flex布局中,单独某个元素挪到右侧、底部,与其他元素排列不同,就像是个另类。(主要是用到margin-left和align-self)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
|
4月前
|
前端开发 容器
前端基础(十五)_多栏布局(两列自适应布局、圣杯布局---三列布局、双飞翼布局--三列布局、等高布局)
本文介绍了前端开发中的多种自适应布局技术,包括两列自适应布局、圣杯布局(三列布局)、双飞翼布局(三列布局)和等高布局。文章通过代码示例展示了如何使用HTML和CSS实现这些布局,以及如何通过flex布局简化实现过程。
164 2
|
8月前
|
前端开发 容器
如何实现一个两栏布局,右侧自适应?三栏布局中间自适应?
要实现一个两栏布局,右侧自适应的效果,可以使用 CSS 的 Flexbox 或 Grid 布局来实现。以下是使用 Flexbox 实现的示例:
86 1
|
8月前
|
索引
消除游戏中图标下落的原理和实现
消除游戏中图标下落的原理和实现
59 1
|
UED 容器
如何实现侧边两栏宽度固定,中间栏宽度自适应的布局?——双飞翼布局、圣杯(Holy Grails)布局
如何实现侧边两栏宽度固定,中间栏宽度自适应的布局?——双飞翼布局、圣杯(Holy Grails)布局
95 0
|
iOS开发
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)
147 0
iOS开发 - 渐变导航条升级版(判断滚动的方向和改变方向时的位置)
|
前端开发 容器
通俗重制系列--Grid布局
通俗重制系列--Grid布局
152 0
|
前端开发 JavaScript 计算机视觉
css动画:文字向上移动并逐渐消失 点击按钮显示+1上移淡出
css动画:文字向上移动并逐渐消失 点击按钮显示+1上移淡出
1145 0
css动画:文字向上移动并逐渐消失 点击按钮显示+1上移淡出
|
前端开发
html+css鼠标经过的样式变化例题
当用户移动鼠标到指定的区域或内容时,会出现什么不一样的渲染效果呢?看这篇文章一起来了解吧!
154 0
 html+css鼠标经过的样式变化例题