2016-08-19 129 views
1

当ViewHolder中的感兴趣的视图移动到窗口边界之外时,是否有一种检测甚至更好,获得通知的好方法(已滚动或部分滚动关闭)?检测视图在RecyclerView.ViewHolder中部分可见

我在想,一个选择是设置滚动监听器上RecyclerView和检查我LayoutManagerfindFirstCompletelyVisibleItemPosition()等,并计算其观点不再可见。喜欢的东西:

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

你有什么理由想这样做呢? –

+0

我有ExoPlayer在RecyclerView内播放视频。 ViewHolder中可以有多个视频。一旦至少有一个滚动屏幕,我需要停止播放器并释放资源。 – vkislicins

+0

也许'View.getVisibility()'更有效率。我不确定这是否会完全满足您的使用情况。 –

回答

1

在这种情况下是有用的人,这是我落得这样做:

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 
     } 
    } 
} 
+0

谢谢,它帮助了我。 – LeShChEnKoUa