RecyclerView流式布局StaggeredGridLayoutManager,重排序问题

RecyclerView天然支持流式布局,只需要设置layoutManager为StaggeredGridLayoutManager,不过如果item中有图片,由于图片异步加载,会导致item布局变化,这倒也没什么,关键是在holder复用的过程中,由于图片异步加载,原先的图片尺寸与即将要加载的图片尺寸不一样,就导致上下滑动的时候,因为item默认是按照哪边有空缺,就先填充哪边,比如原本的顺序如下:
RecyclerView流式布局StaggeredGridLayoutManager,重排序问题_第1张图片
假如加载item10开始复用holder,则下一屏复用后如下,注意,此时图片都未加载完成
RecyclerView流式布局StaggeredGridLayoutManager,重排序问题_第2张图片
第二屏的状态下还未复服用holder8和holder9,
假设下图未图片加载完成后的状态,注意,图片加载完成后只会改变holder高度,不会重排序
RecyclerView流式布局StaggeredGridLayoutManager,重排序问题_第3张图片
现在假设我们再往回滑动,可以肯定的是,不管图片有没有缓存,滑动回顶部的时候,顶部holder一定是无法对其的。下图未滑动回顶部时holder加载状态及图片加载完成后item状态如下
RecyclerView流式布局StaggeredGridLayoutManager,重排序问题_第4张图片
左图为holder状态,图片未加载完成,注意,往上滑item是从下往上填充的,图片加载完成后如右图所示,与左图对应关系为
holder8 -> item9,
holder9 -> item8,
holder7 -> item7,
holder6 -> item6,
holder5 -> item5,
holder3 -> item4,
holder4 -> item3,
holder2 -> item2,
holder1 -> item1
但是可以看到的是此时item顺序与最初时完全不同,同时recyclerview为了确保顶部对齐,会移动item,所以会造成item移动的动画。这明显不是我们想要的。我们想要的是原来怎么样,回来还是怎么样。怎么做呢?其中一个办法就在图片加载前先确定图片尺寸,这是最简单有效的办法,也就是在holder复用时优先确定尺寸,这样原来item在什么位置,还是什么位置,图片尺寸不会变,位置不会变。
怎么做呢,使用图片框架加载图片时,在图片加载完成后,根据bitmap的宽高比计算出Imageview的尺寸,因为imageview宽度固定,所以很容易计算出需要的高度。一旦图片加载过就有尺寸信息,所有在滑动时总是能提前设置图片高度,而没加载过得图片只会是在往下加载更多图片的时候触发,而此时不需要提前知道图片尺寸,由加载完成后动态填充。因为往下滑滑到底部是不需要对齐的。而往上滑因为已经缓存了图片尺寸也能正确排序。
但是。。。。
这样做还是有概率会重排,问题出在往下滑动的时候,由于第一次不知道图片尺寸,这时候的图片排序和加载完成再回划时知道图片尺寸的排序(固定的)不一定相同。这样做只能确保加载过的图片来回滑动不会有问题。

最稳妥最完全的解决方案还是需要一开始就知道图片尺寸,然后bindHolder的时候就设置好尺寸,否则就目前看来这就是一个无解的问题

你可能感兴趣的:(Android)