Fade In Fade Out Animazione Android in Java


148

Voglio avere un'animazione di 2 secondi di un ImageView che spenda 1000ms in dissolvenza e poi 1000ms in dissolvenza.

Ecco cosa ho finora nel mio costruttore 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);

Quando eseguo quell'animazione, non viene visualizzato nulla . Tuttavia, quando rimuovo una delle animazioni alfa, il comportamento funziona come previsto.

Cose che ho già provato:

  • Ogni possibile combinazione di setFillBefore, setFillAftere setFillEnabled.
  • Aggiunta di a LinearInterpolatora AnimationSet.

1
Sì, puoi sfumare le immagini dentro e fuori! Questo tutorial dovrebbe fare il trucco. sankarganesh-info-exchange.blogspot.com/2011/04/…
— Adam Storm

Quel tutorial descrive un metodo usando XML. Sai come ottenere la stessa cosa usando Java?
— Ploughman,

Bene, non sono accanto al mio computer di programmazione, quindi non posso testare questo codice, ma puoi impostare gli attributi XML in Java. questo è il codice originale: android: interpolator = "@ android: anim / accelerate_interpolator" android: fromAlpha = "0.0" android: toAlpha = "1.0" android: duration = "300" /> \ n, quindi puoi probabilmente MyTween.setDurationg (300) MyTween.fromAlpha (0.0) MyTween (1.0)
— Adam Storm

Risposte:


258

Ho capito il mio problema. La soluzione è stata basata su interpolatori.

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


Se stai 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
E se volessi fare 5 o 6 dissolvenze in / out, con ritardi davvero piccoli come 100 per ciascuno, potresti usare qualcosa del genere? Ci ho provato ma non è davvero fluido. Lo scopo era simulare ad esempio una lampadina che non funzionava correttamente e scintillare.
— Chayy,

prova a chiamare this.setAnimation in a loop
— Jonathan

Stavo pensando di sfumare l'ultimo bg img e dissolvenza in quello attuale, ma questa risposta mi ispira che ho solo bisogno di svanire nel bg img attuale e sfumare quello attuale, perché AlphaAnimation non può sbiadire / rimuovere due diversi img .
— macio.

8
Non penso che tu debba avere due animazioni indipendenti ... Penso che potresti avere una sola animazione e impostare il parametro: fadeInOut.setRepeatMode (Animation.REVERSE);
— RoundSparrow hilltx,

Secondo: se volessi ripetere, non c'è bisogno di chiamare in un ciclo come ha detto @jonney. usa fadeInOut.setRepeatCount (6) - cambia 6 per essere il numero che desideri ripetere. Molto meno sovraccarico per consentire al codice C ++ nativo in Android di fare tutto questo invece di chiamare in un ciclo Java.
— RoundSparrow hilltx,

137

So che è già stata data una risposta, ma .....

<?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"
    />

Modo semplice e veloce per eseguire rapidamente una dissolvenza in entrata e in uscita con una ripetizione automatica. Godere

EDIT : nella tua attività aggiungi questo:

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

6
+1 Perché con questa risposta ho potuto mettere in sicurezza la dissolvenza in entrata, in dissolvenza e in dissolvenza (solo impostando repeatCount = "2"). Non sono riuscito a concatenare le animazioni come propone la risposta accettata.
— ElYeante,

1
Dopo aver dichiarato questa alpharisorsa come posso usarla ?. Grazie
— zozelfelfo

1
zozelfelfo è solo un xml di animazione, quindi caricalo in codice e poi chiama startAnimation su qualunque vista tu voglia che abbia effetto.
— Konrad Winkowski,

Il metodo startAnimation @KonradWinkowski richiede l'oggetto Animation come argomento! cosa dovrei passare ad esso?
— Ahmad Vatani,

Per chi cerca una risposta più completa viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out):, dove c'è un file fade_in_out.xml nella cartella anim sotto 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();

4
Elegante per Marshmallow!
— Lasciamo il

26

Ecco la mia soluzione usando AnimatorSet che sembra essere un po 'più affidabile di 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();

Ho dovuto usare un ObjectAnimator invece di un'animazione per ottenere una soluzione funzionante perché per qualche motivo, ogni volta che ho avviato AlphaAnimation, ha funzionato due volte e ha fatto uno strano sfarfallio.
— Andrew Orobator,

soluzione elegante
— Vlad,

Beh, è ​​troppo tardi, ma penso che questo potrebbe essere d'aiuto in qualche animazione gentile e chiara prima di usarla di nuovo nella stessa vista ..
— Bhavesh Moradiya,

21

Un'altra alternativa:

Non è necessario definire 2 animazioni per fadeIn e fadeOut . fadeOut è il contrario di fadeIn .

Quindi puoi farlo con Animation.REVERSE in questo modo:

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

quindi onAnimationEnd :

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

Come credo nel potere di XML (per i layout), questo è l'equivalente per la risposta accettata , ma puramente come risorsa di animazione:

<?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>

È necessario fillAfterche la dissolvenza rimanga dopo aver completato l'animazione. Le interpolatormaniglie interpolazione delle animazioni, come si può intuire. Puoi anche utilizzare altri tipi di interpolatori, come Linear o Overshoot.

Assicurati di avviare l'animazione a vista:

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

@KGCybeX nessun problema, felice di poterti aiutare :)
— DarkCygnus

1
Molto utile e pulito. Funziona perfettamente per me.
— Fernando Barbosa,

9

Ecco cosa ho usato per dissolvenza in / out Views, spero che questo aiuti qualcuno.

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

In qualche modo questa è l'unica risposta che include l'impostazione della visibilità, bello
— Luca

8

I set di animazione non sembrano funzionare come previsto. Alla fine ho rinunciato e ho usato postDelayed () della classe Handler per sequenziare le animazioni.


8

Se usi Animator per creare animazioni, puoi farlo

anim (directory) -> 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"/>

A java

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

Un altro modo per far svanire l'animazione con solo codice java è

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

nella directory anim * not animator
— kosas

4

Puoi anche usare animationListener, qualcosa del genere:

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

0

Mi piace molto la soluzione Vitaly Zinchenkos poiché è stata breve.

Ecco una versione ancora più breve di kotlin per una semplice dissolvenza

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.