studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android layout view height

para - manual de programacion android pdf



Android: obtenga la altura de una vista antes de que se dibuje (6)

Ok, con respecto a la publicación actualizada, esto es lo que te ayudará: Método de Animation#initialize . Deberías poner la inicialización allí en lugar del constructor, y tendrás todos los tamaños que necesites allí.

Para una animación, necesito saber la altura desde una vista. El problema es que el método getHeight () devuelve siempre 0 a menos que se dibuje la vista. Entonces, ¿hay alguna forma de obtener altura sin dibujarla?

En este caso, la vista es un LinearLayout.

EDITAR: Intento adaptar la animación expandida de https://github.com/Udinic/SmallExamples/blob/master/ExpandAnimationExample/src/com/udinic/expand_animation_example/ExpandAnimation.java

Con esto quiero expandir más información para un elemento de la lista. No pude lograr el mismo efecto a través de xml. Por el momento, la animación solo funciona cuando conoces el tamaño del diseño antes de dibujarlo.


Parece que quieres obtener la altura pero ocultar la vista antes de que sea visible.

Tenga la visibilidad en la vista configurada como visible o invisible para comenzar (solo para que se cree una altura). No se preocupe, lo cambiaremos 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 ); } });


Podría intentar comenzar con la vista visible y luego 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 llame a view.getHeight (), debe devolver la altura que espera.

No estoy seguro de si realmente es una buena manera de hacerlo, pero al menos debería funcionar.


Técnicamente, puede llamar al método de measure en la vista y luego obtener su altura a través de getMeasureHeight . Consulte esto para obtener más información: https://developer.android.com/guide/topics/ui/how-android-draws.html . MeasureSpec embargo, tendrá que darle una MeasureSpec .

Pero, en realidad, el tamaño de la vista está influenciado por su diseño principal, por lo que puede obtener un tamaño diferente al que realmente se dibuja.

Además, puede intentar usar valores RELATIVE_TO_SELF en sus animaciones.


Tuve un problema similar con una situación similar.

Tuve que crear una anmiación para la cual requería la altura de la view que está sujeta a la animación. Dentro de esa view , que es LinearLayout puede ser una vista secundaria de tipo TextView . Ese TextView es multilínea y la cantidad de líneas realmente requeridas varía.

Todo lo que hice acabo de obtener la altura medida para la vista como si el TextView tuviera solo una línea para llenar. No es de extrañar que esto funcionara bien cada vez que el texto resultaba lo suficientemente corto para una sola línea, pero falló cuando el texto era más largo en línea.

Consideré esta respuesta: https://.com/a/6157820/854396 Pero esa no me funcionó demasiado bien porque no puedo acceder al TextView incrustado directamente desde aquí. (Sin embargo, podría haber iterado a través del árbol de vistas de niños).

Eche un vistazo a mi código ya que funciona por ahora:

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

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 casi todo, pero cometí otro error. Dentro de la jerarquía de vistas hay dos vistas personalizadas involucradas que son subclases de LinearLayout y su xml se fusiona con una etiqueta de merge como etiqueta de raíz xml. Dentro de una de estas etiquetas de merge pasé por alto para configurar el atributo android:orientation en vertical . Eso no molestó demasiado para el diseño en sí, porque dentro de este ViewGroup fusionado ViewGroup había un ViewGroup secundario y, por lo tanto, no podía ver la orientación incorrecta en la pantalla. Pero estaba allí y rompió un poco esta lógica de medición de diseño.

Además de lo anterior, puede ser necesario deshacerse de todos los rellenos asociados con LinearLayout sy subclases dentro de la jerarquía de vistas. Reemplácelos por los márgenes, incluso si tiene que envolver otro diseño alrededor para que se vea igual.


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(); }