2015-05-22 25 views
22

Ho un RecyclerView che si trova all'interno di un CardView. Lo CardView ha un'altezza di 500 dpi, ma desidero abbreviare questa altezza se lo RecyclerView è più piccolo. Quindi mi chiedo se ci sia un listener chiamato quando lo RecyclerView ha terminato la posa dei suoi articoli per la prima volta, rendendo possibile impostare l'altezza dello RecyclerView sull'altezza dello CardView (se inferiore a 500dp).Come sapere quando RecyclerView ha terminato la posa degli articoli?

+0

Trovato qualcosa? Ne ho davvero bisogno anch'io. – Magnas

+0

Correlati: http://stackoverflow.com/questions/32496681/how-to-know-when-data-is-loaded-inside-custom-recyclerview –

risposta

29

Avevo anche bisogno di eseguire il codice dopo che la mia vista del riciclatore ha finito di gonfiare tutti gli elementi. Ho provato a verificare in onBindViewHolder nel mio adattatore, se la posizione era l'ultimo, e quindi ha notificato l'osservatore. Ma a quel punto, la vista del riciclatore non era ancora completamente popolata.

come RecyclerView strumenti ViewGroup, this anwser è stato molto utile. Hai semplicemente bisogno di aggiungere un OnGlobalLayoutListener al recyclerView:

View recyclerView=findViewById(R.id.myView); 
     recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        //At this point the layout is complete and the 
        //dimensions of recyclerView and any child views are known. 
       } 
      }); 
+13

questo metodo è chiamato più volte e non solo quando è finito. Non ha funzionato per me – Juancho

+5

@Juancho funziona se rimuovi il listener dopo averlo terminato con 'onGlobalLayout'? –

+3

@NeonWarge sì funziona rimuovendo l'ascoltatore nella prima chiamata, grazie! – Juancho

-2

Quello che ha funzionato per me è stato quello di aggiungere il listener dopo aver impostato l'adattatore RecyclerView.

ServerRequest serverRequest = new ServerRequest(this); 
serverRequest.fetchAnswersInBackground(question_id, new AnswersDataCallBack() 
{ 
    @Override 
    public void done(ArrayList<AnswerObject> returnedListOfAnswers) 
    { 
     mAdapter = new ForumAnswerRecyclerViewAdapter(returnedListOfAnswers, ForumAnswerActivity.this); 
     recyclerView.setAdapter(mAdapter); 
     recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
     { 
      @Override 
      public void onGlobalLayout() 
      { 
       progressDialog.dismiss(); 
      } 
     }); 
    } 
}); 

Questa congeda il "progressDialog" dopo lo stato di layout globale o la visibilità di punti di vista all'interno dei cambiamenti visualizzazione ad albero.

15

Modifica di lavoro di @andrino anwser.

Come @Juancho ha indicato nel commento sopra. Questo metodo è chiamato più volte. In questo caso, vogliamo che venga attivato solo una volta.

Creato listener personalizzato con un'istanza per esempio

private RecyclerViewReadyCallback recyclerViewReadyCallback; 

public interface RecyclerViewReadyCallback { 
    void onLayoutReady(); 
} 

Quindi impostare OnGlobalLayoutListener sul RecyclerView

recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       if (recyclerViewReadyCallback != null) { 
        recyclerViewReadyCallback.onLayoutReady(); 
       } 
       recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      } 
     }); 

dopo che avete solo bisogno di implementare listener personalizzato con il codice

recyclerViewReadyCallback = new RecyclerViewReadyCallback() { 
      @Override 
      public void onLayoutReady() { 
       // 
       //here comes your code that will be executed after all items has are laid down 
       // 
      } 
}; 
1

ho stato alle prese con il tentativo di rimuovere OnGlobalLayoutListener una volta attivato ma che lancia un IllegalStateException. Dal momento che quello che mi serve è quello di scorrere la mia recyclerView al secondo elemento quello che ho fatto è stato quello di verificare se già avere figli e se è la prima volta che questo è vero, solo allora mi fare il rotolo:

public class MyActivity extends BaseActivity implements BalanceView { 
    ... 
    private boolean firstTime = true; 
    ... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ... 

     ViewTreeObserver vto = myRecyclerView.getViewTreeObserver(); 
     vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       if (myRecyclerView.getChildCount() > 0 && MyActivity.this.firstTime){ 
        MyActivity.this.firstTime = false; 
        scrollToSecondPosition(); 
       } 
      } 
     }); 
    } 
    ... 
    private void scrollToSecondPosition() { 
     // do the scroll 
    } 
} 

HTH qualcuno!

(Naturalmente, questo è stato ispirato alle risposte @andrino e @Phatee)

Problemi correlati