Android RecyclerView如何在ItemDecoration中找到第一个和最后一个视图

25

这是我的情景

  • 我需要在 Recycler View 的第一个和最后一个项目上添加间距
  • 我正在使用ItemDecoration来实现

 recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {


    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int totalHeight = parent.getHeight();
        int viewHeight = getResources().getDimensionPixelOffset(R.dimen.breadcrumb_btn_height);
        int padding = (totalHeight - viewHeight) / 2;
        //to position view on middle
        if (view.getTag() instanceof Integer) {
            int position = (int) view.getTag();
            if (position == 0) {
                //first position
                outRect.set(padding, padding, 0, padding);
            } else if (position == linearLayoutManager.getItemCount() - 1)   {
                //last position
                outRect.set(0, padding, padding, padding);
            } else {
                outRect.set(0, padding, 0, padding);
            }
        }


    }
});

这里我有一个

  • 使用水平方向的LinearLayoutManager

    我以以下方式在RecyclerView Adapter中添加了position标签

  • @Override
    public void onBindViewHolder(BreadCrumbViewHolder holder, int position) {
    holder.setPosition(position);
    }
    

    有没有其他的方式可以在 ItemDecoration 中访问 RecyclerView 的第一个和最后一个子项,以便稍后删除和添加项目时不会出现任何问题。

    1个回答

    68

    是否有其他方法可以在ItemDecoration中访问RecyclerView的第一个和最后一个子项,以便稍后删除和添加项时不会出现任何问题。

    是的。您只需实现自己的ItemDecoration即可实现想要的效果。

    要获取当前项目/子项位置:

    int position = parent.getChildAdapterPosition(view);
    

    获取项目/子项的数量:

    int itemCount = state.getItemCount();
    

    使用此方法,您可以在 RecyclerView 的第一个和最后一个子项中添加一个 空格


    现在,根据这种方法更改您的代码,您将获得:

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
    
        //your padding...
    
        final int itemPosition = parent.getChildAdapterPosition(view);
        if (itemPosition == RecyclerView.NO_POSITION) {
            return;
        }
    
        final int itemCount = state.getItemCount();
    
        /** first position */
        if (itemPosition == 0) {
            outRect.set(padding, padding, 0, padding);
        }
        /** last position */
        else if (itemCount > 0 && itemPosition == itemCount - 1) {
            outRect.set(0, padding, padding, padding);
        }
        /** positions between first and last */
        else {
            outRect.set(0, padding, 0, padding);
        }
    }
    
    奖励:如果您想给RecyclerView的所有项添加填充,请查看我创建的Gisthttps://gist.github.com/ryanamaral/93b5bd95412baf85a81a

    2
    太棒了,谢谢。请使用parent.getChildPosition(view)而不是parent.getChildAdapterPosition(view) - laaptu
    @laaptu getChildPosition方法已被弃用。文档建议使用getChildAdapterPosition或getChildLayoutPosition。 - John Slavick
    2
    在这种情况下,我认为你应该使用getChildLayoutPosition(view)state.getItemCount()相结合,而不是使用getChildAdapterPosition(view)。它们考虑了当前布局传递中的位置,这可能比适配器中的位置更旧。 - BladeCoder
    4
    我无法相信四年过去了,原始回答后没有人发现这在所有情况下都不起作用。如果你阅读State.getItemCount()的文档,你会发现新添加的项不会反映在此计数中。这意味着你对于“第一个”或“最后一个”位置的计算是错误的。 - ievgen
    1
    @ievgen 这份文档并没有反映出你所说的“新添加的项未在此计数中反映”。它确实说新添加的项不会在预布局遍历中反映,但它们将在第二次布局遍历中被看到。 - Michael Krause
    显示剩余2条评论

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接