2010-05-19 8 views
11

que tienen un diseño que especifica tamaños de los widgets en la dimensión relativa, por ejemplo:¿Cómo obtener el tamaño de un widget de Android después de calcular el diseño?

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

Inmediatamente después de onCreate, quiero saber cuánto es la altura de la ImageView. ¿Como hacer eso?

Nota: Si llamogetHeight() en onCreate, me sale 0.

También he intentado imageView.postDelayed, funciona en 2.1 emulador pero falla en emulador 1,5 (0 llegué, también).

Finalmente, traté de crear un Handler, y luego llamé a handler.postDelayed con 10 ms de retraso. Funciona tanto en el emulador 2.1 como en el 1.5, pero falla al iniciar el programa en eclipse depurador (Entonces, concluyo que usar el retraso no garantiza que la obtención de la altura ocurra después de que la vista de la imagen se diseñe).

Respuesta

11

El motivo por el que obtienes un tamaño de 0 es que el diseño no se completa hasta después de que la actividad se haya creado por completo, es decir, se hayan procesado onCreate(), onStart() y onResume(). La manera más fácil que conozco para obtener el tamaño exacto es llamar a su método una vez que el diseño ha finalizado, como al utilizar un oyente de clic en un botón. Como el botón no se muestra hasta que finaliza el diseño, el tamaño debe estar disponible para cuando se active el detector de clics.

Esto es solo una suposición, pero imagino que esto es difícil de hacer precisamente porque no quieren que la gente se meta con los tamaños de diseño una vez que el sistema acaba de terminar de colocar la pantalla. Si proporcionan una devolución de llamada "onLayoutFinished()", entonces podrías quedarte atrapado en un bucle si modificaras el diseño en eso. Por ejemplo, imagine: el diseño está completo; onLayoutFinished() llamado y usted modifica el diseño allí; el diseño existente ahora no es válido; diseño re-hecho; onLayoutFinished() llamado de nuevo; su código se llama nuevamente, y así sucesivamente.

Otra forma de hacerlo es crear una vista personalizada y anular el método onMeasure(int, int). El sistema activa ese método para obtener el tamaño de cada Vista; si se utiliza algo así como mi ejemplo a continuación, se puede obtener el sugirió tamaño antes de que termine el diseño:

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

(escribí que es el tamaño recomendado, porque creo que es posible que el tamaño sea cambiado después esto se basa en restricciones de diseño. Sin embargo, ese es un vago recuerdo de algo que leí hace un tiempo, y nunca experimenté en detalle). Una vez que hayas hecho eso, puedes usar el tamaño para lo que sea que quisieras hacer: incluso puede cambiar el tamaño que usará usando setMeasuredDimension(newX, newY).

+0

Muchas gracias. Eso suena el camino. Probaré eso. – yuku

+2

Esta es una gran limitación en mi humilde opinión. No ser capaz de obtener medidas sin anular una Vista o Diseño o agregar un botón que realmente no necesita. –

7

El objeto View proporciona un método llamado onSizeChanged (int w, int h, int oldw, int oldh). Se invoca cuando el diseño cambia el tamaño de uno de sus componentes. Si reemplaza este método, el código en su versión de este método conocerá el tamaño de sí mismo como se muestra en el siguiente fragmento.

@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 
} 
Cuestiones relacionadas