Android: mostrar/ocultar una vista usando una animación

5 minutos de lectura

avatar de usuario
Blaskovicz

He estado buscando en muchos resultados/preguntas de Google aquí para determinar cómo mostrar/ocultar una vista a través de una animación vertical, pero parece que no puedo encontrar uno que sea exactamente correcto o no demasiado vago.

Tengo un diseño (barra de deshacer) que está debajo de otro diseño y encima de varios otros widgets; esta barra de deshacer debe abrirse y cerrarse verticalmente, según las circunstancias.

Actualmente, todo lo que hago en este momento es configurar la vista para que sea visible o desaparezca.

Establecer el atributo
android:animateLayoutChanges="true"
dentro del diseño principal.

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

NOTA: Esto funciona solo desde API Nivel 11+ (Android 3.0)

avatar de usuario
Rotemmiz

Creé una extensión para RelativeLayout que muestra/oculta diseños con animaciones. Puede extender cualquier tipo de View para obtener estas características.

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;

public class AnimatingRelativeLayout extends RelativeLayout
{
    Context context;
    Animation inAnimation;
    Animation outAnimation;

    public AnimatingRelativeLayout(Context context)
    {
        super(context);
        this.context = context;
        initAnimations();

    }

    public AnimatingRelativeLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.context = context;
        initAnimations();
    }

    public AnimatingRelativeLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.context = context;
        initAnimations();
    }

    private void initAnimations()
    {
        inAnimation = (AnimationSet) AnimationUtils.loadAnimation(context, R.anim.in_animation);
        outAnimation = (Animation) AnimationUtils.loadAnimation(context, R.anim.out_animation);
    }

    public void show()
    {
        if (isVisible()) return;
        show(true);
    }

    public void show(boolean withAnimation)
    {
        if (withAnimation) this.startAnimation(inAnimation);
        this.setVisibility(View.VISIBLE);
    }

    public void hide()
    {
        if (!isVisible()) return;
        hide(true);
    }

    public void hide(boolean withAnimation)
    {
        if (withAnimation) this.startAnimation(outAnimation);
        this.setVisibility(View.GONE);
    }

    public boolean isVisible()
    {
        return (this.getVisibility() == View.VISIBLE);
    }

    public void overrideDefaultInAnimation(Animation inAnimation)
    {
        this.inAnimation = inAnimation;
    }

    public void overrideDefaultOutAnimation(Animation outAnimation)
    {
        this.outAnimation = outAnimation;
    }
}

Puede anular el original Animationestá usando overrideDefaultInAnimation y overrideDefaultOutAnimation

Mis animaciones originales eran fadeIn/Out, estoy agregando archivos de animación XML para traducir dentro/fuera de la pantalla (Traducir hacia arriba y desde arriba)

en_animación.xml:

    <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="600"
    android:fillAfter="false"
    android:fromXDelta="0"
    android:fromYDelta="-100%p"
    android:toXDelta="0"
    android:toYDelta="0" />

salida_animación.xml:

  <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="600"
    android:fillAfter="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="0"
    android:toYDelta="-100%p" />

avatar de usuario
Rudi Kershaw

Esto se puede lograr razonablemente en una declaración de una sola línea en API 12 y superior. A continuación se muestra un ejemplo donde v es la vista que desea animar;

v.animate().translationXBy(-1000).start();

Esto deslizará la View en cuestión a la izquierda por 1000px. Para deslizar la vista de regreso a la interfaz de usuario, simplemente podemos hacer lo siguiente.

v.animate().translationXBy(1000).start();

Espero que alguien encuentre esto útil.

Si solo desea animar la altura de una vista (desde 0 hasta un cierto número), puede implementar su propia animación:

final View v = getTheViewToAnimateHere();
Animation anim=new Animation(){
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        // Do relevant calculations here using the interpolatedTime that runs from 0 to 1
        v.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, (int)(30*interpolatedTime)));
    }};
anim.setDuration(500);
v.startAnimation(anim);

He usado estas dos funciones para ocultar y mostrar la vista con animación de transición sin problemas.

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void expand(final View v, int duration, int targetHeight, final int position) {

        int prevHeight = v.getHeight();

        v.setVisibility(View.VISIBLE);
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0, targetHeight);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                v.getLayoutParams().height = (int) animation.getAnimatedValue();
                v.requestLayout();
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.setDuration(duration);
        valueAnimator.start();
        valueAnimator.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                v.clearAnimation();
            }
        });

    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void collapse(final View v, int duration, int targetHeight, final int position) {
        if (position == (data.size() - 1)) {
            return;
        }
        int prevHeight = v.getHeight();
        ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                v.getLayoutParams().height = (int) animation.getAnimatedValue();
                v.requestLayout();
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.setDuration(duration);
        valueAnimator.start();
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                animBoolArray.put(position, false);
                v.clearAnimation();

            }
        });
    }

Tratar de usar TraducirAnimación class, que crea la animación para los cambios de posición. Intenta leer esto para obtener ayuda: http://developer.android.com/reference/android/view/animation/TranslateAnimation.html

Actualización: Aquí está el ejemplo para esto. Si tiene la altura de su vista como 50 y en el modo oculto, desea mostrar solo 10 px. El código de ejemplo sería:

TranslateAnimation anim=new TranslateAnimation(0,0,-40,0);
anim.setFillAfter(true);
view.setAnimation(anim);

PD: Hay muchos u otros métodos para ayudarlo a usar la animación de acuerdo con sus necesidades. También eche un vistazo a RelativeLayout.LayoutParams si desea personalizar completamente el código, sin embargo, usar TranslateAnimation es más fácil de usar.

EDITAR: -Versión compleja usando LayoutParams

RelativeLayout relParam=new RelativeLayout.LayoutParam(RelativeLayout.LayoutParam.FILL_PARENT,RelativeLayout.LayoutParam.WRAP_CONTENT); //you can give hard coded width and height here in (width,height) format.
relParam.topMargin=-50; //any number that work.Set it to 0, when you want to show it.
view.setLayoutParams(relparam);

Este código de ejemplo asume que está colocando su vista en RelativeLayout, si no cambia el nombre de Layout, sin embargo, es posible que otro diseño no funcione. Si desea darles un efecto de animación, reduzca o aumente el margen superior lentamente. Puede considerar usar Thread.sleep() allí también.

avatar de usuario
Timofey Stolbov

Prueba esto.

view.animate()
    .translationY(0)
    .alpha(0.0f)
    .setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            view.setVisibility(View.GONE);
        }
    });

¿Ha sido útil esta solución?