当ViewHolder中的一个感兴趣的视图移出窗口边界(滚动或部分滚动)时,是否有一种检测甚至更好,获得通知的好方法?
我认为一个选项是在RecyclerView
上设置滚动侦听器并检查我的LayoutManager
findFirstCompletelyVisibleItemPosition()
等,并计算哪些视图不再可见。类似的东西:
private RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
calculateVisibility();
}
};
其中calculateVisibility()
将在每个滚动事件上运行,但这只会让我看到我的ViewHolder位置,而不是实际的ViewHolders或这些视图持有者中的单个视图。这意味着我需要从布局管理器中查找位置的实际布局,然后测量视图支架内的各个视图。类似的东西:
private void calculateVisibility() {
if (!isAdded() || !getUserVisibleHint() || mAdapter == null) {
return;
}
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == -1
&& mLayoutManager.findLastCompletelyVisibleItemPosition() == -1
&& mLayoutManager.findFirstVisibleItemPosition() == -1
&& mLayoutManager.findLastVisibleItemPosition() == -1) {
return;
}
int firstPartiallyVisiblePosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
int lastPartiallyVisiblePosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
View v = mLayoutManager.findViewByPosition(firstPartiallyVisiblePosition);
for (v instanceof MySpecialView) {
boolean visible = isViewVisible(v);
// do stuff based on visibility
}
}
这感觉它的效率非常低。
我可以在适配器内找到的方法似乎与回收和分离更相关,如果你只是滚动屏幕视图就不会发生这种情况。
也许有人做过类似的事情?
答案 0 :(得分:2)
如果这对任何人都有用,这就是我最终做的事情:
private void calculateVisibility() {
if (!isAdded() || !getUserVisibleHint() || mAdapter == null
|| mAdapter.getItemCount() == 0) {
return;
}
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == -1
&& mLayoutManager.findLastCompletelyVisibleItemPosition() == -1
&& mLayoutManager.findFirstVisibleItemPosition() == -1
&& mLayoutManager.findLastVisibleItemPosition() == -1) {
return;
}
int findFirstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
int findLastVisibleItemPosition = mLayoutManager.findLastVisibleItemPosition();
int [] positions = {findFirstVisibleItemPosition, findLastVisibleItemPosition};
ViewHolder viewHolder;
Rect scrollBounds = new Rect();
mRecyclerView.getDrawingRect(scrollBounds);
int location[] = new int[2];
for (int position : positions) {
viewHolder = mRecyclerView.getChildViewHolder(
mLayoutManager.findViewByPosition(position));
viewHolder.getMySpecialView().getLocationInWindow(location);
if (location[1] < 0 || location[1] > scrollBounds.bottom) {
// do stuff
}
}
}