Fade In Fade Out Animación de Android en Java


148

Quiero tener una animación de 2 segundos de un ImageView que gasta 1000ms desvaneciéndose y luego 1000ms desvaneciéndose.

Esto es lo que tengo hasta ahora en mi constructor ImageView:

Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setDuration(1000);

Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);

AnimationSet animation = new AnimationSet(true);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
this.setAnimation(animation);

Cuando ejecuto esa animación, no aparece nada . Sin embargo, cuando elimino una de las animaciones alfa, el comportamiento funciona como se esperaba.

Cosas que ya he probado:

  • Todas las combinaciones imaginables de setFillBefore, setFillAftery setFillEnabled.
  • Agregar un LinearInterpolatora la AnimationSet.

1
¡Sí, puedes desvanecer las imágenes dentro y fuera! Este tutorial debería hacer el truco. sankarganesh-info-exchange.blogspot.com/2011/04/…
Adam Storm

Ese tutorial describe un método usando XML. ¿Sabes cómo lograr lo mismo con Java?
labrador

Bueno, no estoy al lado de mi computadora de programación, así que no puedo probar este código, pero puedes establecer atributos xml en Java. este es el código original: android: interpolator = "@ android: anim / accelerate_interpolator" android: fromAlpha = "0.0" android: toAlpha = "1.0" android: Duration = "300" /> \ n para que pueda MyTween.setDurationg (300) MyTween.fromAlpha (0.0) MyTween (1.0)
Adam Storm

Respuestas:


258

Descubrí mi propio problema. La solución terminó por basarse en interpoladores.

Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
fadeIn.setDuration(1000);

Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); //and this
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);

AnimationSet animation = new AnimationSet(false); //change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
this.setAnimation(animation);


Si está usando Kotlin

val fadeIn = AlphaAnimation(0f, 1f)
fadeIn.interpolator = DecelerateInterpolator() //add this
fadeIn.duration = 1000

val fadeOut = AlphaAnimation(1f, 0f)
fadeOut.interpolator = AccelerateInterpolator() //and this
fadeOut.startOffset = 1000
fadeOut.duration = 1000

val animation = AnimationSet(false) //change to false
animation.addAnimation(fadeIn)
animation.addAnimation(fadeOut)
this.setAnimation(animation)

1
¿Qué sucede si desea hacer 5 o 6 desvanecimientos de entrada / salida, con retrasos realmente pequeños como 100 para cada uno, podría usar algo como esto? Lo intenté pero no es realmente fluido. El objetivo era simular, por ejemplo, una bombilla que no funcionaría correctamente y centellear.
Chayy

tratar de llamar this.setAnimation en un bucle
Jonathan

Estaba pensando que me desvanecería el último bg img y la moda en el actual, pero esta respuesta me inspira que solo necesito desvanecerme en el bg img actual y desvanecer el actual, porque AlphaAnimation no puede desvanecer / apagar dos imgs diferentes .
macio.

8
No creo que necesite tener dos animaciones independientes ... Creo que podría tener una sola animación y establecer el parámetro: fadeInOut.setRepeatMode (Animation.REVERSE);
RoundSparrow hilltx

Segundo: si desea repetir, no necesita llamar en un bucle como dijo @jonney. use fadeInOut.setRepeatCount (6): cambie 6 para que sea la cantidad que desea que se repita. Mucho menos sobrecarga para permitir que el código nativo de C ++ en Android haga todo esto en lugar de llamar a un bucle Java.
RoundSparrow hilltx

137

Sé que esto ya ha sido respondido pero .....

<?xml version="1.0" encoding="utf-8"?> 
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0" 
    android:toAlpha="0.0" 
    android:duration="1000"    
    android:repeatCount="infinite" 
    android:repeatMode="reverse"
    />

Forma rápida y fácil de hacer un fundido de entrada y salida con una repetición automática. Disfrutar

EDITAR : en su actividad agregue esto:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.yourAnimation));

66
+1 Porque con esta respuesta podría hacer una secuencia de fundido de entrada, desvanecimiento y desvanecimiento (simplemente configurando repeatCount = "2"). No pude concatenar animaciones como propone la respuesta aceptada.
ElYeante

1
Después de declarar este alpharecurso, ¿cómo puedo usarlo? Gracias
zozelfelfo

1
zozelfelfo es solo un xml de animación, así que cárguelo en el código y luego llame a startAnimation en cualquier vista que desee que afecte.
Konrad Winkowski

@KonradWinkowski ¡El método startAnimation requiere un objeto Animation como argumento! ¿Qué debo pasarle?
Ahmad Vatani

Para aquellos que buscan una respuesta más completa: viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out)donde hay un archivo fade_in_out.xml en la carpeta anim bajo res.
Chris Knight

32
viewToAnimate.animate().alpha(1).setDuration(1000).setInterpolator(new DecelerateInterpolator()).withEndAction(new Runnable() {
    @Override
    public void run() {
        viewToAnimate.animate().alpha(0).setDuration(1000).setInterpolator(new AccelerateInterpolator()).start();
    }
}).start();

44
Elegante para Marshmallow!
Deja

26

Aquí está mi solución usando AnimatorSet, que parece ser un poco más confiable que AnimationSet.

// Custom animation on image
ImageView myView = (ImageView)splashDialog.findViewById(R.id.splashscreenImage);

ObjectAnimator fadeOut = ObjectAnimator.ofFloat(myView, "alpha",  1f, .3f);
fadeOut.setDuration(2000);
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(myView, "alpha", .3f, 1f);
fadeIn.setDuration(2000);

final AnimatorSet mAnimationSet = new AnimatorSet();

mAnimationSet.play(fadeIn).after(fadeOut);

mAnimationSet.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        mAnimationSet.start();
    }
});
mAnimationSet.start();

Tuve que usar un ObjectAnimator en lugar de una animación para obtener una solución que funcionara porque, por alguna razón, cada vez que comencé una AlphaAnimation, se ejecutó dos veces e hizo un parpadeo extraño.
Andrew Orobator

solución elegante
Vlad

Bueno, es demasiado tarde, pero creo que esto podría ayudar a algunos, animación amablemente clara antes de usarlo nuevamente en la misma vista ...
Bhavesh Moradiya

21

Otra alternativa:

No es necesario definir 2 animaciones para fadeIn y fadeOut . fadeOut es inverso a fadeIn .

Entonces puedes hacer esto con Animation.REVERSE así:

AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setDuration(1000);
alphaAnimation.setRepeatCount(1);
alphaAnimation.setRepeatMode(Animation.REVERSE);
view.findViewById(R.id.imageview_logo).startAnimation(alphaAnimation);

luego enAnimationEnd :

alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
        public void onAnimationStart(Animation animation) {
            //TODO: Run when animation start
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            //TODO: Run when animation end
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            //TODO: Run when animation repeat
        }
    });

12

Como creo en el poder de XML (para diseños), este es el equivalente de la respuesta aceptada , pero puramente como un recurso de animación:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/accelerate_decelerate"
    android:fillAfter="true">
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="1000" />
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="1000"
        android:startOffset="1000"/>
</set>

El fillAfteres para que el desvanecimiento permanezca después de completar la animación. La interpolación de interpolatormanijas de las animaciones, como puedes adivinar. También puede usar otros tipos de interpoladores, como Linear o Overshoot.

Asegúrese de comenzar su animación en su vista:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.fade));

@KGCybeX no hay problema, me alegro de poder ayudar :)
DarkCygnus

1
Muy servicial y limpio. Funciona perfectamente para mi.
Fernando Barbosa

9

Esto es lo que solía desvanecer en Vistas, espero que esto ayude a alguien.

private void crossFadeAnimation(final View fadeInTarget, final View fadeOutTarget, long duration){
    AnimatorSet mAnimationSet = new AnimatorSet();
    ObjectAnimator fadeOut = ObjectAnimator.ofFloat(fadeOutTarget, View.ALPHA,  1f, 0f);
    fadeOut.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            fadeOutTarget.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    });
    fadeOut.setInterpolator(new LinearInterpolator());

    ObjectAnimator fadeIn = ObjectAnimator.ofFloat(fadeInTarget, View.ALPHA, 0f, 1f);
    fadeIn.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            fadeInTarget.setVisibility(View.VISIBLE);
        }

        @Override
        public void onAnimationEnd(Animator animation) {}

        @Override
        public void onAnimationCancel(Animator animation) {}

        @Override
        public void onAnimationRepeat(Animator animation) {}
    });
    fadeIn.setInterpolator(new LinearInterpolator());
    mAnimationSet.setDuration(duration);
    mAnimationSet.playTogether(fadeOut, fadeIn);
    mAnimationSet.start();
}

De alguna manera, esta es la única respuesta que incluye establecer la visibilidad, agradable
Luke

8

AnimationSets no parecen funcionar como se esperaba en absoluto. Al final me di por vencido y usé el postDelayed () de la clase Handler para secuenciar animaciones.


8

Si usa Animator para hacer animación, puede

anim (directorio) -> fade_out.xml

<?xml version="1.0" encoding="UTF-8"?>
<objectAnimator
    android:propertyName="alpha"
    android:valueFrom="0"
    android:valueTo="1"
    xmlns:android="http://schemas.android.com/apk/res/android"/>

En java

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.fade_out);
animator.setTarget(the_view_you_want_to_animation);
animator.setDuration(1000);
animator.start();

Otra forma de hacer que la animación se desvanezca con solo código java es

ObjectAnimator fadeOut = ObjectAnimator.ofFloat(the_view_you_want_to_animation, "alpha",  1f, 0);
fadeOut.setDuration(2000);
fadeOut.start();

en el directorio anim * no animador
kosas

4

También puedes usar animationListener, algo como esto:

fadeIn.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation animation) {
        this.startAnimation(fadeout);
    }
});

0

Realmente me gusta la solución de Vitaly Zinchenkos ya que fue corta.

Aquí hay una versión aún más breve en Kotlin para un desvanecimiento simple

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.