我需要知道哪些元素目前显示在我的RecyclerView。ListViews上没有与OnScrollListener.onScroll(…)方法等价的方法。我试图与view . getglobalvisibl勃起(…)工作,但黑客是太丑陋,并不总是工作太。

有人有什么想法吗?


当前回答

第一个/最后一个可见子节点依赖于LayoutManager。 如果您正在使用LinearLayoutManager或GridLayoutManager,您可以使用

int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();

例如:

GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();

对于LinearLayoutManager,第一个/最后一个取决于适配器的顺序。不要从RecyclerView中查询子元素;LayoutManager可能更倾向于布局比缓存可见的更多的项。

其他回答

上面的每个答案都是正确的,我也想添加一个快照从我的工作代码。

recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
           // Some code when initially scrollState changes
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // Some code while the list is scrolling
            LinearLayoutManager lManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            int firstElementPosition = lManager.findFirstVisibleItemPosition();
            
        }
    });

最后,我找到了一个解决方案,从适配器中的onBindViewHolder事件了解当前项是否可见。

关键是来自LayoutManager的isViewPartiallyVisible方法。

在您的适配器中,您可以从RecyclerView中获得LayoutManager,它作为参数从onAttachedToRecyclerView事件中获得。

第一个/最后一个可见子节点依赖于LayoutManager。 如果您正在使用LinearLayoutManager或GridLayoutManager,您可以使用

int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();

例如:

GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();

对于LinearLayoutManager,第一个/最后一个取决于适配器的顺序。不要从RecyclerView中查询子元素;LayoutManager可能更倾向于布局比缓存可见的更多的项。

对于那些需要在RecyclerView适配器中实现逻辑的人来说,您仍然可以使用@ernesto方法结合on scrollListener来在咨询RecyclerView时获得您想要的东西。 在适配器内部,你会有这样的东西:

@Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
            LinearLayoutManager llm = (LinearLayoutManager) manager;
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                }

                @Override
                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                        int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
                        if(visiblePosition > -1) {
                            View v = llm.findViewByPosition(visiblePosition);
                            //do something
                            v.setBackgroundColor(Color.parseColor("#777777"));
                        }
                }
            });
        }
    }

您可以使用recyclerView.getChildAt()来获取每个可见的子视图,并在适配器代码中对这些视图设置一些convertview.setTag(index)标记将帮助您将其与适配器数据关联起来。