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.