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.

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)

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

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

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

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

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

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

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.


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

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

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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.