在RecyclerView中进行调整时,StaggeredLayoutManager会干扰单元格的位置

时间:2019-04-02 05:53:09

标签: android android-recyclerview recyclerview-layout staggered-gridview staggeredgridlayout

StaggeredLayoutManager有时会在尝试调整它们时使它们在滚动过程中位置混乱。我的RecyclerView中有HeaderView和NormalViews。以下是设置代码:

int spacing = (int) getResources().getDimension(R.dimen.post_item_spacing);
        mBindings.rvPosts.addItemDecoration(new PostsEqualGapItemDecoration(AppConstants.POSTS_SPAN_COUNT, spacing));
        mPostsLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
        mBindings.rvPosts.setLayoutManager(mPostsLayoutManager);
        mProfileAdapter.setRecyclerView(mBindings.rvPosts);
        mBindings.rvPosts.setAdapter(mAdapter);
        mBindings.rvPosts.setNestedScrollingEnabled(false);

ItemDecoration类:

public class PostsEqualGapItemDecoration extends RecyclerView.ItemDecoration {

    private int spanCount;
    private int spacing;

    public PostsEqualGapItemDecoration(int spanCount, int spacing) {
        this.spanCount = spanCount;
        this.spacing = spacing;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

        StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();

        if (layoutParams.isFullSpan()) {
            outRect.set(0, 0, 0, 0);
          } else {
            int spanIndex = layoutParams.getSpanIndex();
            int layoutPosition = layoutParams.getViewLayoutPosition();
            int itemCount = parent.getAdapter().getItemCount();

            boolean leftEdge = spanIndex == 0;
            boolean rightEdge = spanIndex == (spanCount - 1);

            boolean topEdge = spanIndex < spanCount;
            boolean bottomEdge = layoutPosition >= (itemCount - spanCount);

            int halfSpacing = spacing / 2;

            /**
             * Updated values to keep cells width same and spacing from left and right
             * most item to be double than gap between items themselves.
             */
            outRect.set(
                    leftEdge ? spacing * 2 : rightEdge ? 0 : spacing,
                    topEdge ? spacing : halfSpacing,
                    rightEdge ? spacing * 2 : leftEdge ? 0 : spacing,
                    bottomEdge ? spacing : 0
            );


        }
    }
}

屏幕截图:

and

1 个答案:

答案 0 :(得分:0)

You have to write custom item decoration for that case to your child item views
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
  private int space;

  public SpacesItemDecoration(int space) {
    this.space = space;
  }

  @Override
  public void getItemOffsets(Rect outRect, View view, 
      RecyclerView parent, RecyclerView.State state) {
    outRect.left = space;
    outRect.right = space;
    outRect.bottom = space;

    // Add top margin only for the first item to avoid double space between items
    if (parent.getChildLayoutPosition(view) == 0) {
        outRect.top = space;
    } else {
        outRect.top = 0;
    }
  }
}