RecyclerView瀑布流造成的item錯亂

作者:燕歆波
導讀:使用瀑布流時,發現item的順序在滑動時突然順序改變了,造成了設置的間距變化,從而導致整個頁面錯亂。

簡介
在adapter中,我獲取item的位置,根據位置設置item的左右間距:
在這裏插入圖片描述
如果像上面一樣,第一個item比第二個item的高度低的話,那麼是沒有問題的(偶數item在左,奇數item在右);
但是如果第一個item比第二item高的話,就會出現偶數item在右,奇數item在左的問題。
這樣的話,當第二個item高度比第一個item的低時,第三個item將排列在第二個item的下方,
那麼通過position判斷設置間隔的方法就不成立了。這就導致item間隔的錯亂
在查找了一些博客之後,找到了StaggeredLayoutManager.LayoutParams類中有一個getSpanIndex()的方法,可以獲取item在span中的下標。這樣的話問題就可以解決了,只要將position替換爲span的下標判斷item的位置,就不會出現間隔錯亂的問題,(注:這樣是解決了間隔的問題,但是並沒有解決 奇數偶數 item 位置交替的問題)。

```
public class StaggeredGridDivider extends RecyclerView.ItemDecoration {
    private Context context;
    private int interval;

    public StaggeredGridDivider(Context context, int interval) {
        this.context = context;
        this.interval = interval;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
        // 獲取item在span中的下標
        int spanIndex = params.getSpanIndex();
        int interval = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                this.interval, context.getResources().getDisplayMetrics());
        // 中間間隔
        if (spanIndex % 2 == 0) {
            outRect.left = 0;
        } else {
            // item爲奇數位,設置其左間隔
            outRect.left = interval;
        }
        // 上方間隔
        outRect.top = interval;
    }
}
還有一個問題是,從詳情頁回到列表頁時,定位到指定位置回去先頂部空出一片空白的問題,
解決辦法是給RecyclerView添加OnScrollListener,並在其onScrollStateChanged方法中監聽RecyclerView是否滑到頂部,
若滑到頂部,則調用StaggeredLayoutManager的invalidateSpanAssignments方法刷新間隔。

int spanCount = 2
rv.addOnScrollListener(new OnScrollListener() {
  @Override
  public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    int[] first = new int[spanCount];
    layoutManager.findFirstCompletelyVisibleItemPositions(first);
    if (newState == RecyclerView.SCROLL_STATE_IDLE && (first[0] == 1 || first[1] == 1)) {
      layoutManager.invalidateSpanAssignments();
    }  
  } 
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章