Reputation: 13585
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:
setFillBefore
, setFillAfter
, and setFillEnabled
.LinearInterpolator
to the AnimationSet
.Upvotes: 170
Views: 264286
Reputation: 1
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)
Upvotes: 0
Reputation: 1
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()
Upvotes: 0
Reputation: 1189
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()
Upvotes: 4
Reputation: 13585
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);
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)
Upvotes: 290
Reputation: 60913
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();
Upvotes: 11
Reputation: 7838
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(context, R.anim.fade));
Upvotes: 17
Reputation: 2042
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(context, R.anim.yourAnimation));
Upvotes: 166
Reputation: 1824
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
}
});
Upvotes: 24
Reputation: 131
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();
}
Upvotes: 11
Reputation: 4911
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();
Upvotes: 39
Reputation: 667
You can also use animationListener, something like this:
fadeIn.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
this.startAnimation(fadeout);
}
});
Upvotes: 4
Reputation: 4933
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();
Upvotes: 28
Reputation: 1863
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.
Upvotes: 10