2010-05-19 13 views
11

Ho un layout di che specifica le dimensioni di widget in dimensione relativa, ad esempio:Come ottenere le dimensioni di un widget Android dopo aver calcolato il layout?

<LinearLayout ... layout_height="fill_parent"> 
    <ImageView ... layout_height="wrap_content" /> 
    <TextView ... layout_height="120dp" /> 
</LinearLayout> 

Subito dopo onCreate, voglio sapere quanto è l'altezza della ImageView. Come farlo?

Nota: Se chiamo getHeight() in onCreate, ottengo 0.

Ho anche provato imageView.postDelayed, funziona su 2,1 emulatore, ma non riesce a 1,5 emulatore (ho ottenuto 0, anche).

Infine, ho provato a creare un Handler, e quindi chiamo handler.postDelayed con ritardo di 10 ms. Funziona con entrambi gli emulatori 2.1 e 1.5, ma non riesco quando avvio il programma in eclipse debugger (Quindi, concludo che l'utilizzo del ritardo non garantisce che l'altezza venga raggiunta dopo che l'immagine è stata formattata.)

risposta

11

Il motivo per cui si ottiene una dimensione pari a 0 è che il layout non è terminato fino a quando l'attività non è stata completamente creata, ovvero onCreate(), onStart() e onResume() sono stati completati. Il modo più semplice che conosco per ottenere la dimensione esatta è chiamare il metodo dopo che il layout è terminato, ad esempio utilizzando un listener di clic su un pulsante. Poiché il pulsante non viene visualizzato fino al termine del layout, la dimensione deve essere disponibile al momento dell'esecuzione del click listener.

Questa è solo un'ipotesi, ma immagino che questo sia difficile da fare proprio perché non vogliono che la gente tocchi le dimensioni del layout una volta che il sistema ha appena finito di stendere lo schermo. Se hanno fornito un callback "onLayoutFinished()", allora potresti rimanere bloccato in un loop se hai modificato il layout in questo. Ad esempio, immagina: il layout è completato; onLayoutFinished() chiamato e si modifica il layout in là; il layout esistente non è più valido; layout rifatto; onLayoutFinished() chiamato di nuovo; il tuo codice viene chiamato di nuovo e così via.

Un altro modo per farlo è creare una vista personalizzata e sovrascrivere il metodo onMeasure(int, int). Il sistema attiva quel metodo per ottenere le dimensioni di ciascuna vista; se si utilizza qualcosa come il mio esempio qui di seguito, è possibile ottenere il suggerito taglia prima il layout è finito:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    //getMeasuredHeight() and getMeasuredWidth() now contain the suggested size 
} 

(ho scritto che è la dimensione suggerita perché penso che sia possibile per la dimensione per essere cambiato dopo questo si basa sui vincoli del layout, ma è un vago ricordo di qualcosa che ho letto qualche tempo fa, e non ho mai sperimentato in dettaglio.) Una volta che lo hai fatto, puoi usare la dimensione per qualunque cosa tu volessi fare - tu può anche cambiare la dimensione che userà usando setMeasuredDimension(newX, newY).

+0

Grazie mille. Sembra la strada. Ci proverò. – yuku

+2

Questo è un grosso limite IMHO. Non essere in grado di ottenere misure senza sovrascrivere una vista o un layout o aggiungere un pulsante di cui non hai veramente bisogno. –

7

L'oggetto View fornisce un metodo chiamato onSizeChanged (int w, int h, int oldw, int oldh). Viene chiamato quando il layout cambia la dimensione di uno dei suoi componenti. Se si sostituisce questo metodo, il codice nella propria versione di questo metodo conoscerà la dimensione di se stesso come mostrato nel seguente frammento.

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    bounds = new Rect(); 
    this.getDrawingRect(bounds); 
    // bounds will now contain none zero values 
}