我需要知道RecyclerView中当前显示哪些元素。没有等效OnScrollListener.onScroll(...)
于ListViews 的方法。我尝试与一起使用View.getGlobalVisibleRect(...)
,但是这种骇客行为太丑陋,而且并非总是如此。
有人有什么想法吗?
我需要知道RecyclerView中当前显示哪些元素。没有等效OnScrollListener.onScroll(...)
于ListViews 的方法。我尝试与一起使用View.getGlobalVisibleRect(...)
,但是这种骇客行为太丑陋,而且并非总是如此。
有人有什么想法吗?
Answers:
第一个/最后一个可见的孩子取决于LayoutManager
。如果您使用LinearLayoutManager
或GridLayoutManager
,则可以使用
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
例如:
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
对于LinearLayoutManager
,第一个/最后一个取决于适配器的顺序。不要询问来自的孩子RecyclerView
; LayoutManager
对于缓存而言,可能更喜欢布置比可见布局更多的项目。
getItemCount
可以findFirstVisibleItemPosition
在同一通话中返回1和-1。
最后,我从适配器的onBindViewHolder事件中找到了一种解决方案,以了解当前项目是否可见。
关键是LayoutManager中的isViewPartiallyVisible方法。
在您的适配器中,您可以从RecyclerView获取LayoutManager,您可以从onAttachedToRecyclerView事件中将其作为参数获取。
对于那些在RecyclerView适配器内部实现逻辑的用户,您仍然可以使用@ernesto方法与on scrollListener结合使用,以获取what you want
有关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)
在适配器代码中的这些视图上设置一些标签将有助于您将其与适配器数据相关联。
recyclerView.getChildAt()
,这就是通常的RecyclerView
工作方式。RecyclerView
将尝试仅保留当前可见的少数子视图(即,在屏幕范围内,而不是“已消失”,“不可见”),并尝试在用户滚动时回收这些视图。
Linear / Grid LayoutManager
可以使用以下方法检查哪些项目是visible
int findFirstVisibleItemPosition();
int findLastVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
如果您想跟踪is item visible on screen
某个阈值,则可以参考以下博客。
https://proandroiddev.com/detecting-list-items-perceived-by-user-8f164dfb1d05
附录:
建议的功能FindLast中...位置()做不正确的情况下用折叠式工具,而工具栏上展开工作。
似乎回收站视图具有固定的高度,并且在扩展工具栏时,回收站向下移动,部分移出了屏幕。结果,所提出的功能的结果太高。示例:告诉最后一个可见项目是#9,但实际上,项目#7是屏幕上的最后一个项目。
这也是我的视图经常无法滚动到正确位置的原因,即scrollToPosition()不能正常工作(我最终以编程方式折叠了工具栏)。
为此StaggeredGridLayoutManager
:
RecyclerView rv = findViewById(...);
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(...);
rv.setLayoutManager(lm);
并获得可见的项目视图:
int[] viewsIds = lm.findFirstCompletelyVisibleItemPositions(null);
ViewHolder firstViewHolder = rvPlantios.findViewHolderForLayoutPosition(viewsIds[0]);
View itemView = viewHolder.itemView;
请记住检查它是否为空。
viewsIds
是一个数组,它可能为空。