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.