android 瀑布流 向下滑動出現交換位置,頂部空白
問題描述
開發瀑布流時,上下滑動列表,當手動滑到頂部時會出現瀑布流列表的頂部item出現交換的問題; 於是搜了很多的解決方式,大部分都是人云亦云,並無效果,最後還是看到一篇從源碼級別分析此問題,因此解決了這個問題; 現記錄一下:
問題原因
爲什麼會出現交換位置和頂部留白呢, 看到一篇非常詳細的原理分析博客,就不班門弄斧了,想要看原理 ,直接 瀑布流出現交換位置,頂部留白原理解析之傳送門
簡而言之,就是:
1.瀑布流需要每次onBindView時給imageview設置固定的寬高,當 每次向下滑動重用item時,全局刷新會清除mLazySpanLookup
,導致spanIndex
無效, recyclerview填充佈局只能重新計算spanIndex
,然後後面會出現item之間交換的問題;
2.而添加了GapStrategy爲GAP_HANDLING_NONE
後, 因爲瀑布流的item高度都是不一樣的,重新排序之後,就不一定能夠剛好把空間都佔用,留出了頂部的空白。此時只是執行無動畫的交換;
過程
- 設置瀑布流屬性 GapStrategy
首先,大多數答案爲 設置 瀑布流屬性:
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//防止item 交換位置
僅僅 將原先的有動畫交換item 變爲無動畫交換item; 囧~~
- 設置列表監聽 不斷的清除span; (錯誤方法)
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
layoutManager.invalidateSpanAssignments();//防止第一行到頂部有空白
}
});
//StaggeredGridLayoutManager.class
public void invalidateSpanAssignments() {
this.mLazySpanLookup.clear();
this.requestLayout();
}
並沒有什麼卵用, 並且滑動的時候不斷的刷新佈局,對性能也不好;
3.列表中添加數據使用
notifyItemRangeChanged
來刷新就可以解決了;
解決方法
- 瀑布流中的item 通過layoutparams設置固定的大小
- 設置GapStrategy
- 添加數據使用
notifyItemRangeChanged
動態添加;