Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo puedo animar View.setVisibility (GONE)

Quiero hacer una Animation para cuando una View consigue su visibilidad fijada a GONE . En lugar de simplemente desaparecer, la View debería "colapsar". He intentado esto con un ScaleAnimation pero entonces la View es el colapso, pero el diseño sólo se redimensionará su espacio después (o antes) de la Animation detiene (o comienza).

¿Cómo puedo hacer la Animation para que, mientras se anima, la View inferior se quedará directamente debajo del contenido, en lugar de tener un espacio en blanco?

  • SetRetainInstance (true) + setCustomAnimations (...) = animación para cada cambio de orientación?
  • Cómo animar la eliminación de fragmentos
  • ¿Cuál es la forma óptima de animar un dibujable dentro de una vista utilizando las clases de animación?
  • ViewFlipper tiene un retraso "enorme"
  • ¿Cómo encadenar la animación en android a la misma vista?
  • CardView muestra artefactos cuando RotationY> 60
  • ¿Cómo realizar una animación de desvanecimiento en la transición de la actividad?
  • Cómo implementar Diseño de materiales Animaciones de superficie coreográficas
  • 4 Solutions collect form web for “¿Cómo puedo animar View.setVisibility (GONE)”

    No parece ser una manera fácil de hacer esto a través de la API, porque la animación sólo cambia la matriz de representación de la vista, no el tamaño real. Pero podemos establecer un margen negativo para engañar LinearLayout a pensar que la vista se está haciendo más pequeña.

    Por lo tanto, recomiendo crear su propia clase de animación, basada en ScaleAnimation, y reemplazar el método "applyTransformation" para establecer nuevos márgenes y actualizar el diseño. Me gusta esto…

     public class Q2634073 extends Activity implements OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.q2634073); findViewById(R.id.item1).setOnClickListener(this); } @Override public void onClick(View view) { view.startAnimation(new MyScaler(1.0f, 1.0f, 1.0f, 0.0f, 500, view, true)); } public class MyScaler extends ScaleAnimation { private View mView; private LayoutParams mLayoutParams; private int mMarginBottomFromY, mMarginBottomToY; private boolean mVanishAfter = false; public MyScaler(float fromX, float toX, float fromY, float toY, int duration, View view, boolean vanishAfter) { super(fromX, toX, fromY, toY); setDuration(duration); mView = view; mVanishAfter = vanishAfter; mLayoutParams = (LayoutParams) view.getLayoutParams(); int height = mView.getHeight(); mMarginBottomFromY = (int) (height * fromY) + mLayoutParams.bottomMargin - height; mMarginBottomToY = (int) (0 - ((height * toY) + mLayoutParams.bottomMargin)) - height; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { int newMarginBottom = mMarginBottomFromY + (int) ((mMarginBottomToY - mMarginBottomFromY) * interpolatedTime); mLayoutParams.setMargins(mLayoutParams.leftMargin, mLayoutParams.topMargin, mLayoutParams.rightMargin, newMarginBottom); mView.getParent().requestLayout(); } else if (mVanishAfter) { mView.setVisibility(View.GONE); } } } } 

    La advertencia habitual se aplica: porque estamos sobreescribiendo un método protegido (applyTransformation), esto no está garantizado para trabajar en futuras versiones de Android.

    Poner la vista en un diseño si no lo es y establecer android:animateLayoutChanges="true" para ese diseño.

    Utilicé la misma técnica que Andy aquí ha presentado. Escribí mi propia clase de Animación para eso, que anima el valor del margen, haciendo que el efecto del elemento desaparezca / aparezca. Se parece a esto:

     public class ExpandAnimation extends Animation { // Initializations... @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { // Calculating the new bottom margin, and setting it mViewLayoutParams.bottomMargin = mMarginStart + (int) ((mMarginEnd - mMarginStart) * interpolatedTime); // Invalidating the layout, making us seeing the changes we made mAnimatedView.requestLayout(); } } } 

    Tengo un ejemplo completo que funciona en mi blog http://udinic.wordpress.com/2011/09/03/expanding-listview-items/

    Utilicé la misma técnica que Andy aquí, y la refiné para que pueda ser usada para expandir y colapsar sin problemas, también usando una técnica descrita aquí: https://stackoverflow.com/a/11426510/1317564

     import android.view.View; import android.view.ViewTreeObserver; import android.view.animation.ScaleAnimation; import android.view.animation.Transformation; import android.widget.LinearLayout; class LinearLayoutVerticalScaleAnimation extends ScaleAnimation { private final LinearLayout view; private final LinearLayout.LayoutParams layoutParams; private final float beginY; private final float endY; private final int originalBottomMargin; private int expandedHeight; private boolean marginsInitialized = false; private int marginBottomBegin; private int marginBottomEnd; private ViewTreeObserver.OnPreDrawListener preDrawListener; LinearLayoutVerticalScaleAnimation(float beginY, float endY, LinearLayout linearLayout) { super(1f, 1f, beginY, endY); this.view = linearLayout; this.layoutParams = (LinearLayout.LayoutParams) linearLayout.getLayoutParams(); this.beginY = beginY; this.endY = endY; this.originalBottomMargin = layoutParams.bottomMargin; if (view.getHeight() != 0) { expandedHeight = view.getHeight(); initializeMargins(); } } private void initializeMargins() { final int beginHeight = (int) (expandedHeight * beginY); final int endHeight = (int) (expandedHeight * endY); marginBottomBegin = beginHeight + originalBottomMargin - expandedHeight; marginBottomEnd = endHeight + originalBottomMargin - expandedHeight; marginsInitialized = true; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (!marginsInitialized && preDrawListener == null) { // To avoid glitches, don't draw until we've initialized everything. preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (view.getHeight() != 0) { expandedHeight = view.getHeight(); initializeMargins(); adjustViewBounds(0f); view.getViewTreeObserver().removeOnPreDrawListener(this); } return false; } }; view.getViewTreeObserver().addOnPreDrawListener(preDrawListener); } if (interpolatedTime < 1.0f && view.getVisibility() != View.VISIBLE) { view.setVisibility(View.VISIBLE); } if (marginsInitialized) { if (interpolatedTime < 1.0f) { adjustViewBounds(interpolatedTime); } else if (endY <= 0f && view.getVisibility() != View.GONE) { view.setVisibility(View.GONE); } } } private void adjustViewBounds(float interpolatedTime) { layoutParams.bottomMargin = marginBottomBegin + (int) ((marginBottomEnd - marginBottomBegin) * interpolatedTime); view.getParent().requestLayout(); } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.