170

I want to have a 2 second animation of an ImageView that spends 1000ms fading in and then 1000ms fading out.

Here's what I have so far in my ImageView constructor:

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

When I run that animation, nothing shows up. However, when I remove one of the alpha animations, the behavior works as expected.

Things I have already tried:

  • Every conceivable combination of setFillBefore, setFillAfter, and setFillEnabled.
  • Adding a LinearInterpolator to the AnimationSet.
3
  • 1
    Yes you can fade images in and out! This tutorial should do the trick. sankarganesh-info-exchange.blogspot.com/2011/04/… Commented Jul 22, 2011 at 22:40
  • That tutorial describes a method using XML. Do you know how to achieve the same thing using Java? Commented Jul 23, 2011 at 0:30
  • Well, Im not next to my programming computer so I cant test this code, but you can set xml attributes in java. this is the original code: android:interpolator="@android:anim/accelerate_interpolator" android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> \n so you can probably MyTween.setDurationg(300) MyTween.fromAlpha(0.0) MyTween(1.0) Commented Jul 23, 2011 at 17:27

14 Answers 14

290

Figured out my own problem. The solution ended up being based in interpolators.

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


If you are using 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)
Sign up to request clarification or add additional context in comments.

7 Comments

What if you want to do 5 or 6 fading in/out, with really small delays like 100 for each, could you use something like this ? I tried but it's not really fluid. The aim was to simulate for example a bulb that would not work properly, and twinkle.
try and call this.setAnimation in a loop
I was thinking I fade out last bg img and fad in the current one, but this answer inspires me that I only need to fade in the current bg img and fade out the current one, cause AlphaAnimation can't fadein/out two different imgs.
I don't think you need to have two independent animations... I think you could have a single animation and set the parameter: fadeInOut.setRepeatMode(Animation.REVERSE);
Second: if you wanted to repeat, no need to call in a loop like @jonney said. use fadeInOut.setRepeatCount(6) - change 6 to be how many you wish it to repeat. Much less overhead to let the native C++ code in Android do all this instead of calling in a Java loop.
|
166

I know that this already has been answered but.....

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

Quick and easy way to quickly do a fade in and out with a self repeat. Enjoy

EDIT : In your activity add this:

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

5 Comments

+1 Because with this answer I could make a secuence of fade in, fade out and fade in (just setting repeatCount="2"). I couldn't concatenating animations as the accepted answer proposes.
After declaring this alpha resource how can I use it?. Thanks
zozelfelfo it is just a animation xml so load it into code and then call startAnimation on whatever view you want it to affect.
@KonradWinkowski startAnimation method requires Animation object as argument! what should i pass to it?
For those looking for a more complete answer: viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out), where there is a fade_in_out.xml file in the anim folder under res.
39
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();

2 Comments

Elegante for Marshmallow!
An important point to note is that you need to reset the setStartDelay() to 0 in the first animation if you are using it in the second animation to delay its start. Else it remembers that delay for any subsequent animation.
28

Here is my solution using AnimatorSet which seems to be a bit more reliable than 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();

3 Comments

I had to use an ObjectAnimator instead of an Animation to get a working solution because for some reason, whenever I started an AlphaAnimation, it ran twice and did some weird flickering.
elegant solution
Well, its too late but I think this might be help some, kindly clear animation before use it again on same view..
24

Another alternative:

No need to define 2 animation for fadeIn and fadeOut. fadeOut is reverse of fadeIn.

So you can do this with Animation.REVERSE like this:

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

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

Comments

17

As I believe in the power of XML (for layouts), this is the equivalent for the accepted answer, but purely as an animation resource:

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

The fillAfter is for the fade to remain after completing the animation. The interpolator handles interpolation of the animations, as you can guess. You can also use other types of interpolators, like Linear or Overshoot.

Be sure to start your animation on your view:

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

2 Comments

@KGCybeX no problem, glad I could help :)
Very helpful and clean. Works perfectly for me.
11

Here is what I used to fade in/out Views, hope this helps someone.

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

1 Comment

Somehow this is the only answer that includes setting visibility, nice
11

If you use Animator for make animation you can

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

In java

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

Other way to make animation fade out with only java code is

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

3 Comments

in directory anim* not animator
@LeTadas in directory animator, according to Android Studio
android:duration="1000"
10

AnimationSets don't appear to work as expected at all. In the end I gave up and used the Handler class's postDelayed() to sequence animations.

Comments

4

You can also use animationListener, something like this:

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

Comments

4

I really like Vitaly Zinchenkos solution since it was short.

Here is an even briefer version in kotlin for a simple fade out

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

Comments

0

Here is another alternative in Kotlin

Done progamatically using ObjectAnimator

  • Uses only one animation

  • Does not muck with the animation listeners

    private fun getFadeAnimation(v: View?): ObjectAnimator 
      return ObjectAnimator.ofFloat(v, "alpha", .3f, 1f).apply {
          repeatCount = ObjectAnimator.INFINITE
          repeatMode = ObjectAnimator.REVERSE
          duration = 1000
      }
    }
    

Create only one instance in the activity and then use:

val animator = getFadeAnimator(myView)
animator.start()
animator.end()

Comments

0

Create an "anim" directory in it:

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="1000" >

Create an "anim" directory in it:

val fadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in)
    imageView.startAnimation(fadeIn)

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0
class SplashActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_splash)

        val logo = findViewById\<ImageView\>(R.id.logoImage)

        val animation = AnimationUtils.loadAnimation(this, R.anim.fade_in)

        logo.startAnimation(animation)

        Handler(Looper.getMainLooper()).postDelayed({

            val intent = Intent(this, MainActivity::class.java)

            startActivity(intent)

            overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)

            finish()

        }, 2000)

    }

}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.