Fade In Fade Out Android Animation w Javie


148

Chcę mieć 2-sekundową animację ImageView, która spędza 1000 ms na zanikaniu, a następnie 1000 ms na zanikaniu.

Oto, co mam do tej pory w moim konstruktorze 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);

Kiedy uruchamiam tę animację, nic się nie pojawia. Jednak kiedy usuwam jedną z animacji alfa, zachowanie działa zgodnie z oczekiwaniami.

Rzeczy, których już próbowałem:

  • Każdej możliwej kombinacji setFillBefore, setFillAfteri setFillEnabled.
  • Dodawanie LinearInterpolatordo AnimationSet.

1
Tak, możesz pojawiać się i znikać obrazy! Ten samouczek powinien załatwić sprawę. sankarganesh-info-exchange.blogspot.com/2011/04/…
Adam Storm

W tym samouczku opisano metodę używającą XML. Czy wiesz, jak osiągnąć to samo za pomocą Javy?
oracz

Cóż, nie jestem obok mojego komputera do programowania, więc nie mogę przetestować tego kodu, ale możesz ustawić atrybuty xml w java. to jest oryginalny kod: android: interpolator = "@ android: anim / Accelerate_interpolator" android: fromAlpha = "0.0" android: toAlpha = "1.0" android: duration = "300" /> \ n więc prawdopodobnie możesz MyTween.setDurationg (300) MyTween.fromAlpha (0.0) MyTween (1.0)
Adam Storm,

Odpowiedzi:


258

Zrozumiałem swój problem. Ostatecznie rozwiązanie zostało oparte na interpolatorach.

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


Jeśli używasz 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
A co jeśli chcesz zrobić 5 lub 6 stopni wejścia / wyjścia, z naprawdę małymi opóźnieniami, takimi jak 100 dla każdego, czy możesz użyć czegoś takiego? Próbowałem, ale to nie jest naprawdę płynne. Celem było zasymulowanie na przykład żarówki, która nie działałaby prawidłowo i migotała.
Chayy

spróbuj nazwać this.setAnimation w pętli
Jonathan

Myślałem, że znikam ostatni bg img i fad w obecnym, ale ta odpowiedź inspiruje mnie, że muszę tylko zniknąć w bieżącym bg img i zaniknąć bieżący, ponieważ AlphaAnimation nie może zniknąć / zgasić dwóch różnych obrazów .
macio,

8
Myślę, że nie potrzebujesz dwóch niezależnych animacji ... Myślę, że możesz mieć jedną animację i ustawić parametr: fadeInOut.setRepeatMode (Animation.REVERSE);
RoundSparrow hilltx

Po drugie: jeśli chcesz powtórzyć, nie musisz dzwonić w pętli, jak powiedział @jonney. użyj fadeInOut.setRepeatCount (6) - zmień 6 na liczbę powtórzeń. Znacznie mniej narzutów, aby umożliwić natywnemu kodowi C ++ w systemie Android to wszystko zamiast wywoływania pętli Java.
RoundSparrow hilltx

137

Wiem, że już na to odpowiedziano, ale .....

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

Szybki i łatwy sposób na szybkie wprowadzanie i wyłączanie z powtarzaniem samego siebie. Cieszyć się

EDYCJA : W swojej aktywności dodaj to:

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

6
+1 Ponieważ z tą odpowiedzią mógłbym zrobić zabezpieczenie wejścia, zanikania i zanikania (po prostu ustawiając repeCount = "2"). Nie mogłem łączyć animacji zgodnie z akceptowaną odpowiedzią.
ElYeante,

1
Po zadeklarowaniu tego alphazasobu, jak mogę z niego korzystać? Dzięki
zozelfelfo

1
zozelfelfo to po prostu plik XML animacji, więc załaduj go do kodu, a następnie wywołaj startAnimation w dowolnym widoku, na który ma to wpłynąć.
Konrad Winkowski

@KonradWinkowski metoda startAnimation wymaga obiektu Animation jako argumentu! co mam do niego przekazać?
Ahmad Vatani

Dla tych, którzy szukają pełniejszej odpowiedzi: viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out)gdzie w folderze anim pod res. Znajduje się plik fade_in_out.xml.
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 for Marshmallow!
LETs

26

Oto moje rozwiązanie wykorzystujące AnimatorSet, które wydaje się być nieco bardziej niezawodne niż 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();

Musiałem użyć ObjectAnimator zamiast Animation, aby uzyskać działające rozwiązanie, ponieważ z jakiegoś powodu za każdym razem, gdy uruchamiałem AlphaAnimation, uruchamiało się ono dwukrotnie i powodowało dziwne migotanie.
Andrew Orobator

eleganckie rozwiązanie
Vlad

Cóż, jest już za późno, ale myślę, że może to pomóc w jakiejś życzliwej animacji przed ponownym użyciem jej w tym samym widoku ..
Bhavesh Moradiya

21

Inna alternatywa:

Nie ma potrzeby definiowania 2 animacji dla fadeIn i fadeOut . fadeOut jest odwrotnością fadeIn .

Możesz to zrobić za pomocą Animation.REVERSE w następujący sposób:

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

potem 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

Ponieważ wierzę w siłę XML (dla układów), jest to odpowiednik zaakceptowanej odpowiedzi , ale wyłącznie jako zasób animacji:

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

fillAfterJest dla blaknięcie pozostać po zakończeniu animacji. Jak można się domyślić, interpolatorobsługuje interpolację animacji. Możesz także użyć innych typów interpolatorów, takich jak Linear lub Overshoot.

Pamiętaj, aby rozpocząć animację w swoim widoku:

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

@KGCybeX żadnego problemu, zadowolony, że mogłem pomóc :)
DarkCygnus

1
Bardzo pomocny i czysty. U mnie działa idealnie.
Fernando Barbosa

9

Oto, czego użyłem do zanikania / wyłączania widoków, mam nadzieję, że to komuś pomoże.

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

Jakoś to jedyna odpowiedź, która obejmuje ustawienie widoczności, fajnie
Łukasz

8

AnimationSets nie wydaje się działać zgodnie z oczekiwaniami. W końcu zrezygnowałem i użyłem postDelayed () klasy Handler do sekwencjonowania animacji.


8

Jeśli używasz Animatora do tworzenia animacji, możesz

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

W java

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

Innym sposobem na zanikanie animacji za pomocą samego kodu java jest

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

w katalogu anim * not animator
kosas

4

Możesz także użyć animacjiListener, czegoś takiego:

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

0

Bardzo podoba mi się rozwiązanie Witalija Zinczenki , ponieważ było krótkie.

Oto jeszcze krótsza wersja w kotlinie dla prostego zanikania

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.