2016-08-19 66 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