我需要知道哪些元素目前显示在我的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可能更倾向于布局比缓存可见的更多的项。

其他回答

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

对于那些需要在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"));
                        }
                }
            });
        }
    }

如果可见的项目位置与项目位置不同,吐司消息将显示在屏幕上。

myRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);

            LinearLayoutManager manager= (LinearLayoutManager) myRecyclerview.getLayoutManager();
            assert manager != null;
            int visiblePosition = manager.findLastCompletelyVisibleItemPosition();


            if(visiblePosition > -1&&a!=visiblePosition) {
                Toast.makeText(context,String.valueOf(visiblePosition),Toast.LENGTH_SHORT).show();
                //do something
                a=visiblePosition;

            }
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //Some code while the list is scrolling


        }
    });

Addendum: The proposed functions findLast...Position() do not work correctly in a scenario with a collapsing toolbar while the toolbar is expanded. It seems that the recycler view has a fixed height, and while the toolbar is expanded, the recycler is moved down, partially out of the screen. As a consequence the results of the proposed functions are too high. Example: The last visible item is told to be #9, but in fact item #7 is the last one that is on screen. This behaviour is also the reason why my view often failed to scroll to the correct position, i.e. scrollToPosition() did not work correctly (I finally collapsed the toolbar programmatically).

对于那些在Kotlin中寻找答案的人:

fun getVisibleItem(recyclerView : RecyclerView) {
        recyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                 if(newState == RecyclerView.SCROLL_STATE_IDLE) {
                     val index = (recyclerView.layoutManager.findFirstVisibleItemPosition
                     //use this index for any operation you want to perform on the item visible on screen. eg. log(arrayList[index])
                 }
            }
        })
    }

您可以根据您的用例探索获取该职位的其他方法。

int findFirstCompletelyVisibleItemPosition()
int findLastVisibleItemPosition()
int findLastCompletelyVisibleItemPosition()