2015-04-11 11 views
7

Interesuje mnie, jaki jest właściwy i pierwszy możliwy moment, aby uzyskać rozmiar pierwszego elementu z RecyclerView?RecyclerView LayoutManager findViewByPosition zwraca wartość null

Próbowałem użyć:

recyclerView.setLayoutManager(new GridLayoutManager(context, 2)); 
recyclerView.setAdapter(new MyDymmyGridRecyclerAdapter(context)); 
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
     recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
     View firstRecyclerViewItem = recyclerView.getLayoutManager().findViewByPosition(0); 
     // firstRecyclerViewItem is null here 
    } 
}); 

ale zwraca wartość null w tym momencie.

Odpowiedz

3

Jeśli używasz OnGlobalLayoutListener, powinieneś pamiętać, że onGlobalLayout można wywołać wiele razy. Niektóre z tych połączeń może się zdarzyć nawet przed Layoutjest gotowy (i przez gotowy mam na myśli moment, kiedy można dostać wymiary View wywołując view.getHeight() lub view.getWidth()). Więc właściwy sposób wdrożenia swoje podejście byłoby:

recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
     int width = recyclerView.getWidth(); 
     int height = recyclerView.getHeight(); 
     if (width > 0 && height > 0) { 
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { 
       recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      } else { 
       recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
      } 
     } 

     View firstRecyclerViewItem = recyclerView.getLayoutManager().findViewByPosition(0); 
    } 
}); 

Oprócz tego trzeba jeszcze mieć pewność, że w momencie findViewByPosition(0) rozmowy:

  1. elemencie RecyclerView'sAdapter ma co najmniej jeden danych .
  2. View w pozycji 0 jest obecnie widoczny w RecyclerView

mi powiedzieć, czy to rozwiąże problem, jeśli nie jest jeszcze inny sposób z tym, czego potrzebujesz.

0

w moim przedłużony RecyclerView zastąpić onChildAttachedToWindow jak ten

@Override 
public void onChildAttachedToWindow(View child) { 
    super.onChildAttachedToWindow(child); 

    if (!mIsChildHeightSet) { 
     // only need height of one child as they are all the same height 
     child.measure(0, 0); 
     // do stuff with child.getMeasuredHeight() 
     mIsChildHeightSet = true; 
    } 
} 
+0

gdzie zrobić muszę napisać tę metodę obejścia? –

0

miałem tego typu problem. Chcę domyślnie wykonać kliknięcie na pierwszej widocznej pozycji widoku recyler. Napisałem kod na onResume, ale to nie zadziałało. I rozwiązać mój problem pisząc kod w onWindowFocusChanged metodę

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 

    if(isCalledForTheFirstTime) 
    { 
     LinearLayoutManager manager= (LinearLayoutManager) rcViewHeader.getLayoutManager(); 
     int pos= manager.findFirstCompletelyVisibleItemPosition(); 


     View view=manager.findViewByPosition(pos); 
     if(view!=null) 
     { 
      view.performClick(); 
     } 

     // change the vaule so that it would not be call in case a pop up appear or disappear 
     isCalledForTheFirstTime=false; 
    } 

}