2014-10-04 14 views
8

Ho bisogno di ascoltare esattamente un evento di layout globale per impostare inizialmente le posizioni di scorrimento corrette. Dopo aver cercato un po 'perché le mie chiamate a scrollTo(x,y) sembrano ignorate, ho scoperto che queste possono essere richiamate in modo significativo solo dopo che l'intero layout è noto. Quindi sto registrando uno GlobalLayoutListener e rinvio la mia chiamata a scrollTo().Rimuovi listener da ViewTreeObserver

Il problema è che voglio solo fare questo scorrimento una volta. Così ho pensato che potevo semplicemente chiamare removeGlobalOnLayoutListener() per smettere di ascoltare. Ciò ha comportato un'eccezione: IllegalStateException: This ViewTreeObserver is not alive, call getViewTreeObserver() again. Quindi ho pensato che stavo bene, se l'osservatore non è vivo non sparerà nessun evento. Ma sfortunatamente lo fa: la mia vista è scorsa ogni volta che il layout cambia in qualche modo.

La mia attuale iterazione del codice è simile a questa. Cosa posso cambiare per assicurarmi che la chiamata a scrollToGridPos() avvenga solo una volta? So che potrei solo aggiungere un campo locale mHasFired alla classe interna ma che sembra molto sporco trucco per me ...

final ViewTreeObserver vto = mLayout.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    public void onGlobalLayout() { 
     scrollToGridPos(getCenterPoint(), false); 
     if (vto.isAlive()) { 
      vto.removeGlobalOnLayoutListener(this); 
     } 
    } 
}); 
+0

Non mi sembra un trucco. In alternativa puoi anche fare lo stesso all'interno di 'View.onLayout' se puoi sovrascriverlo. Questo sembra più il modo di farlo per me. –

risposta

23

Si dovrebbe solo utilizzare mLayout.getViewTreeObserver() in onGlobalLayout(), piuttosto che cercare di accedere al vecchio uno. Per esempio.

mLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    public void onGlobalLayout() { 
     scrollToGridPos(getCenterPoint(), false); 
     mLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);   
    } 
}); 
+0

Sembra fantastico, ma 'removeGlobalOnLayoutListener' è deprecato. C'è qualche altra soluzione per rimuovere l'ascoltatore? – GA1

+0

Sto usando removeOnGlobalLayoutListener() – musterjunk