Fade In Fade Out Animação Android em Java

148

Eu quero ter uma animação de 2 segundos de um ImageView que gasta 1000ms diminuindo e depois 1000ms diminuindo.

Aqui está o que eu tenho até agora no meu construtor 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 executo essa animação, nada aparece. No entanto, quando removo uma das animações alfa, o comportamento funciona conforme o esperado.

Coisas que eu já tentei:

  • Cada combinação concebível de setFillBefore, setFillAftere setFillEnabled.
  • Adicionando um LinearInterpolatorao AnimationSet.
lavrador
fonte
1
Sim, você pode desbotar e desbotar imagens! Este tutorial deve fazer o truque. sankarganesh-info-exchange.blogspot.com/2011/04/…
Adam Storm
Esse tutorial descreve um método usando XML. Você sabe como conseguir a mesma coisa usando Java?
plowman 23/07
Bem, eu não estou ao lado do meu computador de programação, então não posso testar esse código, mas você pode definir atributos xml em java. este é o código original: android: interpolator = "@ android: anim / accelerate_interpolator" android: fromAlpha = "0.0" android: toAlpha = "1.0" android: duration = "300" /> \ n para que você possa provavelmente MyTween.setDurationg (300) MyTween.fromAlpha (0.0) MyTween (1.0)
Adam Storm

Respostas:

258

Descobri meu próprio problema. A solução acabou sendo baseada em 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);


Se você estiver usando o 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)
lavrador
fonte
1
E se você quiser fazer 5 ou 6 desbotamentos, com atrasos muito pequenos como 100 para cada um, você poderia usar algo assim? Eu tentei, mas não é realmente fluido. O objetivo era simular, por exemplo, uma lâmpada que não funcionasse corretamente e brilhar.
Chayy
tentar chamar this.setAnimation em um loop
Jonathan
Eu estava pensando em desaparecer a última bg img e moda no atual, mas essa resposta me inspira que eu só preciso desaparecer no atual bg img e desaparecer no atual, porque AlphaAnimation não pode desaparecer / img duas imagens diferentes .
macio.Jun
8
Eu não acho que você precise ter duas animações independentes ... Acho que você poderia ter uma única animação e definir o parâmetro: fadeInOut.setRepeatMode (Animation.REVERSE);
você precisa saber é o seguinte
Segundo: se você quiser repetir, não precisa chamar um loop como o @jonney disse. use fadeInOut.setRepeatCount (6) - altere 6 para ser quantos você deseja que ele repita. Muito menos sobrecarga para permitir que o código C ++ nativo no Android faça tudo isso em vez de chamar um loop Java.
você precisa saber é o seguinte
136

Eu sei que isso já foi respondido, mas ...

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

Maneira rápida e fácil de fazer um desvanecimento rápido e automático com uma repetição automática. Aproveitar

EDIT : Na sua atividade, adicione isto:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.yourAnimation));
Konrad Winkowski
fonte
6
+1 Porque, com esta resposta, eu poderia fazer uma seleção de fade in, fade out e fade in (apenas definindo repeatCount = "2"). Não consegui concatenar animações como a resposta aceita propõe.
10382 ElYeante
1
Depois de declarar este alpharecurso, como posso usá-lo? Graças
zozelfelfo
1
O zozelfelfo é apenas um xml de animação, então carregue-o no código e chame startAnimation em qualquer visualização que você queira que ele afete.
Konrad Winkowski
O método startAnimation do @KonradWinkowski requer o objeto Animation como argumento! o que devo passar para ele?
Ahmad Vatani 24/07
Para quem procura uma resposta mais completa viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out):, onde existe um arquivo fade_in_out.xml na pasta anim em res.
22617 Chris Cavaleiro
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();
Vitaly Zinchenko
fonte
4
Elegante para Marshmallow!
Deixou
26

Aqui está minha solução usando o AnimatorSet, que parece ser um pouco mais confiável que o 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();
TWilly
fonte
Eu tive que usar um ObjectAnimator em vez de uma animação para obter uma solução de trabalho porque, por algum motivo, sempre que eu iniciava uma AlphaAnimation, ela rodava duas vezes e fazia alguns movimentos estranhos.
Andrew Orobator
solução elegante
Vlad
Bem, é tarde demais, mas acho que isso pode ser de ajuda alguma, animação gentilmente claro antes de usá-lo novamente no mesmo ponto de vista ..
Bhavesh Moradiya
21

Outra alternativa:

Não é necessário definir 2 animações para fadeIn e fadeOut . fadeOut é o inverso de fadeIn .

Então você pode fazer isso com o Animation.REVERSE assim:

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

em seguida, 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
        }
    });
MartePessoas
fonte
12

Como acredito no poder do XML (para layouts), isso é equivalente à resposta aceita , mas apenas como um recurso de animação:

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

A fillAfteré para o fade para permanecer depois de completar a animação. Ele interpolatormanipula a interpolação das animações, como você pode adivinhar. Você também pode usar outros tipos de interpoladores, como Linear ou Overshoot.

Certifique-se de iniciar sua animação em sua exibição:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.fade));
DarkCygnus
fonte
@KGCybeX nenhum problema, feliz que eu poderia ajudar :)
DarkCygnus
1
Muito útil e limpo. Funciona perfeitamente para mim.
Fernando Barbosa
9

Aqui está o que eu costumava esmaecer dentro / fora do Views, espero que isso ajude alguém.

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();
}
Cristhian Escobar
fonte
De alguma forma, esta é a única resposta que inclui visibilidade configuração, agradável
Luke
8

AnimationSets não parecem funcionar como esperado. No final, desisti e usei o postDelayed () da classe Handler para sequenciar animações.

Richard
fonte
8

Se você usa o Animator para criar animação, pode

anim (diretório) -> 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"/>

Em java

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

Outra maneira de fazer a animação desaparecer apenas com o código java é

ObjectAnimator fadeOut = ObjectAnimator.ofFloat(the_view_you_want_to_animation, "alpha",  1f, 0);
fadeOut.setDuration(2000);
fadeOut.start();
Phan Van Linh
fonte
em anim diretório * não animador
kosas
4

Você também pode usar o animationListener, algo como isto:

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

Eu realmente gosto da solução Vitaly Zinchenkos , pois era curta.

Aqui está uma versão ainda mais breve no kotlin para um desvanecimento simples

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
Marc
fonte