天天看點

關于RecyclerView實作瀑布流,上下滑動時item之間互換位置的問題

  最近項目需求,需要RecyclerView實作瀑布流。在用 StaggeredGridLayoutManager 完成瀑布流的過程中發現一個問題:它并不像pullToRefresh 那樣是穩定的list,而是item之間頻繁交換位置,有時候甚至會出現第一列和第二列完全互換的情況。

  我去搜尋相關的問題,并沒有人非常深入的去寫這個控件,都是一些基礎的用法。好吧,那隻能自食其力,看源碼喽。。。

 源碼中 StaggeredGridLayoutManager 的解釋中有這樣一段話:

Staggered grids are likely to have gaps at the edges of the layout. To avoid these gaps,StaggeredGridLayoutManager can offset spans independently or move items between spans. You can control this behavior via {@link #setGapStrategy(int)}.

大概意思就是說 Staggered grid可能會有一定間距的布局邊緣,為了避免這個問題StaggeredGridLayoutManager提供了解決這個問題的方法。即通過setGapStrategy(int)進行設定。

    public static final int GAP_HANDLING_NONE = 0;

    @Deprecated

    public static final int GAP_HANDLING_LAZY = 1;

    public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2;

  大概意思是:GAP_HANDLING_NONE不為隐藏布局邊緣差距做任何處理。

 GAP_HANDLING_LAZY 已經過期的變量。

GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS  通過item之間互換位置重新調整布局。

當我設定了layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);之後,發現item之間互換位置的情況解決了,但是卻出現了從下往上滑動的時候,第一行的圖檔距離頂端有一定的空白區域。

問題出現隻能繼續解決,等我看了3遍源碼,确實毫無頭緒的時候就大膽試了一下,可能能解決這個問題的辦法, 就在recycleView.addOnScrollListener的 onScrollStateChanged()方法中調用了staggeredGridLayoutManagerlayoutManager.invalidateSpanAssignments()。這樣雖然完全符合了需求,item之間不會調換位置,從下往上滑動的時候,第一行的圖檔距離頂端無空白區域。但是又認真的看到源碼中對此方法的注釋,總是會覺得有點不妥當。

    public void invalidateSpanAssignments() {

        mLazySpanLookup.clear();

        requestLayout();

    } 

解決方案:

recycleView.addOnScrollListener的onScrollStateChanged()的方法中調用staggeredGridLayoutManagerlayoutManager.invalidateSpanAssignments()。

有更好思路的小夥伴請指導