2017-10-09 79 views
2

我正在使用snaphelper回收視圖。 這是我recyclerview:Android - 在位置發生變化時從聽衆回收當前位置

final LinearLayoutManager lm = new LinearLayoutManager(getContext(), 
    LinearLayoutManager.HORIZONTAL, false); 

    recyclerview.setLayoutManager(lm); 

    final PagerSnapHelper snapHelper = new PagerSnapHelper(); 
    snapHelper.attachToRecyclerView(recyclerview); 

當用戶滾動到另一個單元格,我需要做的新的單元位置的東西。

這是我做的就是位置:

 recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
      if (newState != RecyclerView.SCROLL_STATE_IDLE) { 
       return; 
      } 
      if recyclerview == null) { 
       return; 
      } 
      //recyclerview.clearOnChildAttachStateChangeListeners(); 
      int firstVisible = ((LinearLayoutManager) viewerRv.getLayoutManager()).findFirstCompletelyVisibleItemPosition(); 
      if (firstVisible == RecyclerView.NO_POSITION) { 
       return; 
      } 

      doSomething(firstVisible); 
     } 

問題是firstVisible VAR而不是總是給我,例如合適的位置時,我從位置0滾動到9這可能是輸出: 0,1,2,3,4,4,5,9

還有另一種方法來獲得正確的當前位置?

這是什麼最佳實踐?

回答

1

這是我的解決方案:

 recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 
      final int offset = topRv.computeHorizontalScrollOffset(); 
      if (offset % myCellWidth == 0) { 
       final int position = offset/myCellWidth ; 
      } 
     } 
    }); 

是隨時給我的當前位置。

+0

你是怎麼得到'myCellWidth'的? :) –

+0

'myRV.getChildAt(0).measuredWidth' –

+1

最安全的方法是使用addOnGlobalLayoutListener,因爲它可以在視圖真正呈現時給您回調,並且您可以測量視圖並獲得真實值。 希望它幫助你:) – Yoni

0

在您的適配器應該有一個方法叫

@Override 
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { 
       holder.getAdapterPosition(); 
    } 

感謝, 阿南德

1

onScrollStateChanged(int state)的文檔解釋:

  • SCROLL_STATE_IDLE:沒有滾動完成。

  • SCROLL_STATE_DRAGGING:該用戶在屏幕上拖動手指(或它正在程序來完成

  • SCROLL_STATE_SETTLING:用戶中斷了他的手指,並且動畫正在放緩

當狀態爲SCROLL_STATE_DRAGGING或SCROLL_STATE_SETTLING時,你會得到位置,顯然這將返回所有位置,回收視圖已滾動如果你想獲得當前位置,你應該得到當recyclerview停止時(newState = SCROLL_STATE_IDLE)

你可以使用類似的代碼以此爲控制啓動和滾動的兩端:

boolean hasStarted = (state == SCROLL_STATE_DRAGGING); 
boolean hasEnded = (state == SCROLL_STATE_IDLE); 

所以最終的代碼可能會有一些這樣的:

 //Initialize this variable on class that initialize recyclerview 
    private boolean hasStarted; 

    @Override 
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 

     //Scroll is not start and user is dragging his finger 
     if(!hasStarted && newState == SCROLL_STATE_DRAGGING){ 
      hasStarted = true; 
     } 

     //If scroll starts and it finish 
     if(hasStarted && newState == SCROLL_STATE_IDLE){ 
      //Restart variable for next iteration 
      hasStarted = false; 
      //Do something 
      doSomething(firstVisible); 
     } 
    } 
+0

仍然是同樣的問題 – Yoni

+0

編輯您的代碼並添加您從中初始化recyclerview和修改方法的類,以查看該流是正確的。 – Suaro

+0

我在第一部分附上了代碼 – Yoni