¿Cómo recuperar las dimensiones de una vista?

Tengo una vista compuesta de tablelayout, tablerows y textviews. Quiero que parezca una cuadrícula. Necesito obtener la altura y el ancho de esta cuadrícula. Los métodos getheight () y getwidth () siempre devuelven 0. Esto sucede cuando formateo la cuadrícula dinámicamente y también cuando uso una versión xml.

¿Cómo recuperar las dimensiones de una vista?


Aquí está mi programa de prueba que utilicé en Depuración para comprobar los resultados:

import android.app.Activity; import android.os.Bundle; import android.widget.TableLayout; import android.widget.TextView; public class appwig extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.maindemo); //<- includes the grid called "board" int vh = 0; int vw = 0; //Test-1 used the xml layout (which is displayed on the screen): TableLayout tl = (TableLayout) findViewById(R.id.board); tl = (TableLayout) findViewById(R.id.board); vh = tl.getHeight(); //<- getHeight returned 0, Why? vw = tl.getWidth(); //<- getWidth returned 0, Why? //Test-2 used a simple dynamically generated view: TextView tv = new TextView(this); tv.setHeight(20); tv.setWidth(20); vh = tv.getHeight(); //<- getHeight returned 0, Why? vw = tv.getWidth(); //<- getWidth returned 0, Why? } //eof method } //eof class 

13 Solutions collect form web for “¿Cómo recuperar las dimensiones de una vista?”

Creo que el OP se ha ido hace mucho tiempo, pero en caso de que esta respuesta es capaz de ayudar a los futuros buscadores, pensé que publicaría una solución que he encontrado. He añadido este código en mi método onCreate() :

EDITADO: 07/05/11 para incluir código de comentarios:

 final TextView tv = (TextView)findViewById(R.id.image_test); ViewTreeObserver vto = tv.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { LayerDrawable ld = (LayerDrawable)tv.getBackground(); ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0); ViewTreeObserver obs = tv.getViewTreeObserver(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { obs.removeOnGlobalLayoutListener(this); } else { obs.removeGlobalOnLayoutListener(this); } } }); 

Primero obtengo una referencia final a mi TextView (para acceder al método onGlobalLayout() ). A continuación, obtengo el ViewTreeObserver de mi TextView , y agrego un OnGlobalLayoutListener , reemplazando onGLobalLayout (no parece ser un método de superclase para invocar aquí …) y añadiendo mi código que requiere conocer las medidas de la vista en este oyente. Todos los trabajos como se esperaba para mí, por lo que espero que esto es capaz de ayudar.

Voy a añadir una solución alternativa, anular el método onWindowFocusChanged de su actividad y usted será capaz de obtener los valores de getHeight (), getWidth () desde allí.

 @Override public void onWindowFocusChanged (boolean hasFocus) { // the height will be set at this point int height = myEverySoTallView.getMeasuredHeight(); } 

Usted está intentando conseguir el ancho y la altura de los elementos, que no fueron dibujados todavía.

Si utilizas depurar y detener en algún momento, verás que la pantalla de tu dispositivo todavía está vacía, es porque tus elementos no fueron dibujados todavía, así que no puedes obtener el ancho y la altura de algo, que aún no existe.

Y, yo podría estar equivocado, pero setWidth() no siempre es respetado, Layout establece a sus hijos y decide cómo medirlos (llamando child.measure() ), así que si usted establece setWidth() , no está garantizado para obtener Este ancho después del elemento se dibujará.

Lo que necesitas es usar getMeasuredWidth() (la medida más reciente de tu vista) en algún lugar después de que la vista se dibujara en realidad.

Busque en el ciclo de vida de la Activity para encontrar el mejor momento.

http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Creo que una buena práctica es usar OnGlobalLayoutListener como esto:

 yourView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (!mMeasured) { // Here your view is already layed out and measured for the first time mMeasured = true; // Some optional flag to mark, that we already got the sizes } } }); 

Puede colocar este código directamente en onCreate() , y se invocará cuando se establezcan las vistas.

Utilice el método de publicación de la vista como este

 post(new Runnable() { @Override public void run() { Log.d(TAG, "width " + MyView.this.getMeasuredWidth()); } }); 

Intenté usar onGlobalLayout() para hacer algún formato personalizado de un TextView , pero como @George Bailey notó, onGlobalLayout() es de hecho llamado dos veces: una vez en la ruta de diseño inicial, y la segunda vez después de modificar el texto.

View.onSizeChanged() funciona mejor para mí porque si View.onSizeChanged() el texto allí, el método se llama una sola vez (durante el pase de diseño). Esto requirió la TextView de TextView , pero en el nivel API 11+ View. addOnLayoutChangeListener() View. addOnLayoutChangeListener() se puede utilizar para evitar la subclase.

Una cosa más, con el fin de obtener el ancho correcto de la vista en View.onSizeChanged() , el layout_width debe establecer en match_parent , no wrap_content .

Como FX mencionado, puede utilizar un OnLayoutChangeListener a la vista que desea realizar el seguimiento de sí mismo

 view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { // Make changes } }); 

Puede quitar el oyente en la devolución de llamada si sólo desea el diseño inicial.

Supongo que esto es lo que necesita mirar: use onSizeChanged() de su vista. Aquí hay un fragmento de código EXTENDED sobre cómo usar onSizeChanged() para obtener la altura y el ancho de su diseño o vista de forma dinámica http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions .html

¿Está tratando de obtener tamaños en un constructor, o cualquier otro método que se ejecuta antes de obtener la imagen real?

No obtendrá ninguna dimensión antes de que todos los componentes se midan realmente (ya que su xml no sabe acerca de su tamaño de visualización, las posiciones de los padres y lo que sea)

Trate de obtener valores después de onSizeChanged () (aunque se puede llamar con cero), o simplemente esperando cuando obtendrá una imagen real.

Usted debe mirar bastante el ciclo de vida de la visión: http://developer.android.com/reference/android/view/View.html Generalmente usted no debe saber el ancho y la altura para seguro hasta que su actividad viene al estado del onResume.

ViewTreeObserver y onWindowFocusChanged() no son tan necesarios en absoluto.

Si infla TextView como diseño y / o pone algún contenido en él y establece LayoutParams entonces puede usar getMeasuredHeight() y getMeasuredWidth() .

PERO tienes que tener cuidado con LinearLayouts (tal vez también otros ViewGroups ). El problema es que puedes obtener el ancho y la altura después de onWindowFocusChanged() pero si intentas agregar algunas vistas en él, entonces no puedes obtener esa información hasta que todo se haya dibujado. Yo estaba tratando de agregar múltiples TextViews a LinearLayouts para imitar un FlowLayout (estilo de envoltura) y por lo tanto no podía utilizar Listeners . Una vez que el proceso se inicia, debe continuar de forma sincrónica. Así que en tal caso, es posible que desee mantener el ancho de una variable para usarlo más tarde, como durante la adición de vistas al diseño, es posible que lo necesite.

Respuesta simple: Esto funcionó para mí sin problema. Parece que la clave es asegurarse de que la Vista tenga enfoque antes de getHeight, etc. Haga esto usando el método hasFocus (), luego usando el método getHeight () en ese orden. Sólo se necesitan 3 líneas de código.

ImageButton myImageButton1 =(ImageButton)findViewById(R.id.imageButton1); myImageButton1.hasFocus();

int myButtonHeight = myImageButton1.getHeight();

Log.d("Button Height: ", ""+myButtonHeight );//Not required

Espero eso ayude.

Utilice getMeasuredWidth () y getMeasuredHeight () para su vista.

Guía del desarrollador: Ver

CORRECCIÓN: Me di cuenta de que la solución anterior es terrible. Especialmente cuando su teléfono es lento. Y aquí encontré otra solución: calcular el valor de px del elemento, incluyendo los márgenes y los rellenos: dp a px: https://stackoverflow.com/a/6327095/1982712

O dimens.xml a px: https://stackoverflow.com/a/16276351/1982712

Sp a px: https://stackoverflow.com/a/9219417/1982712 (invierta la solución)

O dimens a px: https://stackoverflow.com/a/16276351/1982712

y eso es.

  • ¿Existe alguna diferencia entre "center_horizontal | center_vertical" y "center"
  • Cambiar del diseño main.xml a otro diseño
  • Disposición manchada de Android
  • ¿Cuál es la diferencia entre 'textEmailAddress' y 'textWebEmailAddress'
  • ¿Qué stretchMode utilizar en GridView en android
  • Android: ¿Cómo obtener una vista dada una actividad dentro de una clase normal?
  • No se pudo expandir RemoteViews para: StatusBarNotification
  • Actividad que solo se inicia una vez después de una nueva instalación?
  • Diseño deslizante como google maps v7
  • ¿Cómo puedo utilizar FragmentManager para mostrar Fragmento A, B, C, ... en un FrameLayout?
  • Android hindi chars suave teclado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.