Tengo una vista hecha de TableLayout, TableRow and TextView
. Quiero que se vea como 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 Debug para verificar 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
getHeight()
ygetWidth()
después del ciclo de vida de la Actividad ha pedido a las opiniones que se midan, en otras palabras, hacer este tipo de cosasonResume()
y eso es todo. No debe esperar que un objeto aún no diseñado sepa sus dimensiones, ese es el truco completo. No hay necesidad de la magia sugerida a continuación.getHeight()/Width()
enonResume()
no dió> 0 valor para mí.Respuestas:
Creo que el OP ya no existe, pero en caso de que esta respuesta pueda ayudar a los futuros buscadores, pensé en publicar una solución que he encontrado. He agregado este código a mi
onCreate()
método:EDITADO: 05/07/11 para incluir el código de los comentarios:
Primero obtengo una referencia final a mi
TextView
(para acceder en elonGlobalLayout()
método). A continuación, obtengo elViewTreeObserver
de myTextView
y agrego unaOnGlobalLayoutListener
anulaciónonGLobalLayout
(no parece haber un método de superclase para invocar aquí ...) y agrego mi código que requiere conocer las medidas de la vista en este oyente. Todo funciona como se esperaba para mí, así que espero que esto pueda ayudar.fuente
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
esa manera el oyente debería ser eliminado después de la primera vez se produceaddOnLayoutChangeListener
funciona! :)Solo agregaré una solución alternativa, anularé el método onWindowFocusChanged de tu actividad y podrás obtener los valores de getHeight (), getWidth () desde allí.
fuente
ViewTreeObserver
.Está tratando de obtener el ancho y la altura de un elemento que aún no se dibujó.
Si usa la depuración y se detiene en algún momento, verá que la pantalla de su dispositivo todavía está vacía, porque sus elementos aún no se dibujaron, por lo que no puede obtener el ancho y la altura de algo, eso todavía no existe.
Y, podría estar equivocado, pero
setWidth()
no siempre se respeta,Layout
establece sus hijos y decide cómo medirlos (llamandochild.measure()
), por lo que si configurasetWidth()
, no está garantizado que obtenga este ancho después de que se dibuje el elemento.Lo que necesita es usar
getMeasuredWidth()
(la medida más reciente de su Vista) en algún lugar después de que la vista se dibujó realmente.Examina el
Activity
ciclo de vida para encontrar el mejor momento.http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Creo que una buena práctica es usar
OnGlobalLayoutListener
así:Puede colocar este código directamente
onCreate()
, y se invocará cuando se presenten las vistas.fuente
Use el método de publicación de la Vista de esta manera
fuente
Intenté usar
onGlobalLayout()
para hacer un formateo personalizado de aTextView
, pero como lo notó @George Bailey, enonGlobalLayout()
realidad se llama dos veces: una en la ruta de diseño inicial y la segunda después de modificar el texto.View.onSizeChanged()
funciona mejor para mí porque si modifico el texto allí, el método se llama solo una vez (durante el pase de diseño). Esto requería una subclasificación deTextView
, pero en API Nivel 11+View. addOnLayoutChangeListener()
puede usarse para evitar la subclasificación.Una cosa más, para obtener el ancho correcto de la vista
View.onSizeChanged()
,layout_width
debe establecerse enmatch_parent
, nowrap_content
.fuente
¿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 se midan todos los componentes (ya que su xml no conoce el tamaño de su pantalla, las posiciones de los padres y lo que sea)
Intente obtener valores después de onSizeChanged () (aunque se puede llamar con cero), o simplemente espere cuando obtenga una imagen real.
fuente
Como mencionó FX, puede usar un
OnLayoutChangeListener
para la vista que desea rastrearPuede eliminar el oyente en la devolución de llamada si solo desea el diseño inicial.
fuente
Supongo que esto es lo que necesita mirar: uso
onSizeChanged()
de su vista. Aquí hay un fragmento de código EXTENDIDO sobre cómo usarloonSizeChanged()
para obtener la altura y el ancho de su diseño o vista dinámicamente http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions.htmlfuente
ViewTreeObserver
yonWindowFocusChanged()
no son tan necesarios en absoluto.Si infla el
TextView
diseño como y / o pone algo de contenido en él y lo configuraLayoutParams
, puede usargetMeasuredHeight()
ygetMeasuredWidth()
.PERO tienes que tener cuidado con
LinearLayouts
(tal vez también con otrosViewGroups
). El problema es que puede obtener el ancho y la altura después,onWindowFocusChanged()
pero si intenta agregar algunas vistas, no puede obtener esa información hasta que se haya dibujado todo. Intenté agregar múltiplesTextViews
paraLinearLayouts
imitar unFlowLayout
(estilo de ajuste) y, por lo tanto, no pude usarloListeners
. Una vez que se inicia el proceso, debe continuar sincrónicamente. Entonces, en tal caso, es posible que desee mantener el ancho en una variable para usarlo más tarde, ya que al agregar vistas al diseño, es posible que lo necesite.fuente
A pesar de que la solución propuesta funciona, podría no ser la mejor solución para cada caso porque, según la documentación de
ViewTreeObserver.OnGlobalLayoutListener
lo que significa que se llama muchas veces y no siempre se mide la vista (tiene su altura y ancho determinados)
Una alternativa es usar lo
ViewTreeObserver.OnPreDrawListener
que se llama solo cuando la vista está lista para ser dibujada y tiene todas sus medidas.fuente
Debería ver el ciclo de vida de la vista: http://developer.android.com/reference/android/view/View.html En general, no debe saber con certeza el ancho y la altura hasta que su actividad llegue al estado de reanudar.
fuente
Puede usar una transmisión que se llama en OnResume ()
Por ejemplo:
No puede obtener la altura de una vista en OnCreate (), onStart (), o incluso en onResume () por la razón que respondió kcoppock
fuente
La altura y el ancho son cero porque la vista no se ha creado cuando solicita su altura y ancho. Una solución más simple es
Este método es bueno en comparación con otros métodos, ya que es corto y crujiente.
fuente
Respuesta simple: Esto funcionó para mí sin ningún problema. Parece que la clave es asegurarse de que la vista tenga el foco antes de obtener la altura, etc. Haga esto usando el método hasFocus (), luego usando el método getHeight () en ese orden. Solo se requieren 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.
fuente
Use getMeasuredWidth () y getMeasuredHeight () para su vista.
Guía del desarrollador: Ver
fuente
CORRECCIÓN: Descubrí que la solución anterior es terrible. Especialmente cuando tu teléfono está lento. Y aquí, encontré otra solución: calcular el valor de px del elemento, incluidos 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 (revierta la solución)
o dimens a px: https://stackoverflow.com/a/16276351/1982712
y eso es.
fuente