Para una animación necesito saber la altura de un punto de Vista. El Problema es, que la getHeight() método siempre devuelve 0, a menos que la Vista se dibuja.
Entonces, ¿hay alguna forma de obtener la altura sin dibujo es?

En este caso, la Vista es un LinearLayout.

EDITAR:
Trato de adaptar el ampliar la Animación de https://github.com/Udinic/SmallExamples/blob/master/ExpandAnimationExample/src/com/udinic/expand_animation_example/ExpandAnimation.java

Con esto quiero ampliar algo más de información de un elemento de la lista.
Yo no era capaz de lograr el mismo efecto a través de xml.
En el momento en que la Animación sólo funciona cuando se conozca la distribución de tamaño antes de dibujarlo.

InformationsquelleAutor anonymous | 2012-03-05

7 Comentarios

  1. 124

    Suena a que quieres llegar a la altura pero se esconden de la vista antes de que sea visible.

    Tienen la visibilidad en la vista visible o invisible para empezar(lo justo para que altura es creado). No te preocupes lo vamos a cambiar a invisible/ido en el código como se muestra a continuación:

    private int mHeight = 0;
    private View mView;
    
    class...
    
    //onCreate or onResume or onStart ...
    mView = findViewByID(R.id.someID);
    mView.getViewTreeObserver().addOnGlobalLayoutListener( 
        new OnGlobalLayoutListener(){
    
            @Override
            public void onGlobalLayout() {
                //gets called after layout has been done but before display
                //so we can get the height then hide the view
    
    
                mHeight = mView.getHeight();  //Ahaha!  Gotcha
    
                mView.getViewTreeObserver().removeGlobalOnLayoutListener( this );
                mView.setVisibility( View.GONE );
            }
    
    });
    • Gracias, funciona! Sólo un poco de adición: removeGlobalOnLayoutListener() está en desuso desde la API de nivel 16, es reemplazado por removeOnGlobalLayoutListener()
    • Gracias me ayudó mucho. la medición de los puntos de vista son buggy.
    • Gracias por este consejo, que funcionó muy bien. Nota de lado, el hecho de que el argumento del nombre de la removeOnGlobalLayoutListener es «víctima» es fantástico.
    • Esto no siempre funciona – en primer lugar, a la vista de flash visible antes de desaparecer, lo cual no es bueno para la interfaz de usuario. Segundo, si inicia la aplicación e inmediatamente cambiar a otra aplicación, la altura parece no ser calculado correctamente por el motivo que sea.
  2. 24

    Tuve un problema similar con una situación similar.

    Tuve que crear un anmiation para que me exige la altura de la view que está sujeto a la animación. Dentro de ese view, que es un LinearLayout puede ser hijo de la vista de tipo de TextView. Que TextView es multi línea y el número de líneas que realmente se requiere varía.

    Lo hice yo acabo de recibir la medida de altura de la vista, como si el TextView tiene sólo una línea de llenado. No es de extrañar que este funcionaba bien, cada vez que el texto ha pasado a ser lo suficientemente corto como para una sola línea, pero falló cuando el texto es más largo que en línea.

    He considerado que esta respuesta: https://stackoverflow.com/a/6157820/854396
    Pero el que no funciona demasiado bien para mí, porque yo no soy capaz de acceder a la incrustados TextView directamente desde aquí. (Yo podría haber reiterado a pesar de que el árbol de niño vistas sin embargo.)

    Tener una mirada en mi código como por ahora funciona:

    view es la vista que va a ser animada. Es un LinearLayout
    (La solución final será un poco más el tipo de guardar aquí)
    this es una vista personalizada que contiene view y se hereda de LinearLayout demasiado.

       private void expandView( final View view ) {
    
          view.setVisibility(View.VISIBLE);
    
          LayoutParams parms = (LayoutParams) view.getLayoutParams();
          final int width = this.getWidth() - parms.leftMargin - parms.rightMargin;
    
          view.measure( MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                  MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    
          final int targetHeight = view.getMeasuredHeight();
    
          view.getLayoutParams().height = 0;
    
          Animation anim = new Animation() {
             @Override
             protected void applyTransformation( float interpolatedTime, Transformation trans ) {
                view.getLayoutParams().height =  (int) (targetHeight * interpolatedTime);
                view.requestLayout();
             }
    
             @Override
             public boolean willChangeBounds() {
                return true;
             }
          };
    
          anim.setDuration( ANIMATION_DURATION );
          view.startAnimation( anim );
       }

    Esto fue cerca de él, pero hice otro error. Dentro de la vista de la jerarquía hay dos vistas personalizadas que son subclases de LinearLayout y su xml se combina con un merge etiqueta xml raíz de la etiqueta. Dentro de uno de estos merge etiquetas que pasé por alto para establecer el android:orientation atributo vertical.
    Que no se molestó demasiado por el diseño en sí, porque dentro de este combinado ViewGroup era sólo un niño ViewGroup y por eso no podía ver realmente la orientación incorrecta en la pantalla. Pero ahí estaba y de ordenación de la rompió este esquema de medición de la lógica un poco.

    Además de lo anterior puede ser obligados a deshacerse de todos los rellenos asociados con LinearLayouts y subclases dentro de la vista de jerarquía. Reemplazarlos por los márgenes, incluso si usted tiene que ajustar otro diseño a su alrededor para que se vea de la misma.

    • He perdido dos días. Gracias.
  3. 14

    Técnicamente, usted puede llamar a measure método de la vista y, a continuación, obtener su altura a través de getMeasureHeight. Ver aquí para más info: https://developer.android.com/guide/topics/ui/how-android-draws.html. Usted tendrá que darle un MeasureSpec aunque.

    Pero en realidad, el punto de vista del tamaño es influenciado por su padre el diseño, de modo que usted puede obtener un tamaño diferente que cuando se dibuja.

    También, usted puede intentar el uso de RELATIVE_TO_SELF valores en sus animaciones.

    • De hecho, la altura devuelto por getMeasuredSpec es diferente. En el momento 34 vs 137. He editado el primer mensaje con algo más de información.
    • Ver a mi nueva respuesta.
    • Esta respuesta es la respuesta correcta, pero la falta de código es la simple razón por menos upvotes.
    • Asegúrese de llamar getMeasuredHeight(), no getHeight() después! He descuidado esta poco y pasado un tiempo pensando que esto no funciona.
    • También, usted puede llamar a measure(0,0) si usted no se preocupan por el recorte. Funciona bien.
  4. 5
    static void getMeasurments(View v) {
    
        v.measure(View.MeasureSpec.makeMeasureSpec(PARENT_VIEW.getWidth(), 
          View.MeasureSpec.EXACTLY),
             View.MeasureSpec.makeMeasureSpec(0, 
          View.MeasureSpec.UNSPECIFIED));
    
        final int targetHeight = v.getMeasuredHeight();
        final int targetWidth = v.getMesauredWidth();
    }
    • aunque esta solución funciona (al menos para mí), por favor explique qué hace el código y por qué la próxima vez.
    • ¿Qué es PARENT_VIEW?
    • Esto funciona. Pero, en el primer tiempo, es el cálculo de la altura incluidos los ocultos vistas.
  5. 0

    Ok, con respecto a la actualización del post, esto es lo que le ayudará a:
    Animación#inicializar método. Sólo debe poner de inicialización de ahí, en lugar de el constructor, y usted tendrá todos los tamaños que usted necesita.

    • Hm… no entiendo. Allí, la altura también es 0 a menos que la Vista es visible y no se ha ido.
    • Trate de usar INVISIBLE en lugar de GONE.
    • Podría ser una buena pista. Pero ahora la animación no arranca siempre de inmediato. A veces la primera si me desplazamiento o interactuar con la interfaz de usuario de alguna forma.
    • ¿Cómo se puede asignar la animación a la vista? En qué método y con qué método?
    • Con el diseño.startAnimation(anim); Pero lo pude arreglar el problema con las llamadas de diseño.requestLayout(); Ahora bien, el único problema es, que tengo para android:layout_marginBottom=»-9999dip» para el diseño de shell que ampliarse, porque de lo contrario me puedo configurarlo invisible en lugar del pasado.
  6. 0

    medir a ti mismo si el padre no determinar su tamaño:

    aquí es una extensión de kotlin en vista a hacerlo para siempre:

    fun View.getMeasurments(): Pair<Int, Int> {
        measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
        val width = measuredWidth
        val height = measuredHeight
        return width to height
    }
  7. -6

    Usted podría tratar de empezar con la Vista y, a continuación, agregar algo como esto:

    view.post(new Runnable() {      
        @Override
        public void run() {
            //hide view here so that its height has been already computed
            view.setVisibility(View.GONE);
        }
    });

    Ahora, cuando usted va a llamar a ver.getHeight() debe devolver la altura que se esperaba.

    No estoy seguro de si es realmente una buena manera de hacerlo, pero al menos se debe trabajar.

    • Si usted hace esto, a continuación, se mostrará la vista por primera vez y, a continuación, hacer esto. En el caso donde se desea establecer los parámetros basados en puntos de vista de parámetros, a continuación, nos gustaría hacer algo más.

Dejar respuesta

Please enter your comment!
Please enter your name here