用Java淡入淡出Android动画


148

我想要一个2秒的ImageView动画,该动画花1000ms淡入,然后1000ms淡出。

到目前为止,这是我的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);

当我运行该动画时,没有任何显示。但是,当我删除其中一个alpha动画时,该行为将按预期方式工作。

我已经尝试过的事情:

  • 的所有可能的组合setFillBeforesetFillAftersetFillEnabled
  • 添加LinearInterpolatorAnimationSet

1
是的,您可以淡入和淡出图像!本教程应该可以解决问题。sankarganesh-info-exchange.blogspot.com/2011/04/…–
亚当·斯托姆

该教程描述了一种使用XML的方法。您知道如何使用Java实现同一目标吗?
犁夫

好吧,我不在编程计算机旁,因此我无法测试此代码,但是可以在Java中设置xml属性。这是原始代码:android:interpolator =“ @ android:anim / accelerate_interpolator” android:fromAlpha =“ 0.0” android:toAlpha =“ 1.0” android:duration =“ 300” /> \ n因此您可以选择MyTween.setDurationg (300)MyTween.fromAlpha(0.0)MyTween(1.0)
亚当·斯托姆

Answers:


258

弄清楚我自己的问题。该解决方案最终基于插值器。

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


如果您使用的是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
如果您想进行5或6次淡入/淡出操作,并且每次延迟都非常小,例如100次,您可以使用这种方法吗?我试过了,但并不是很流畅。目的是模拟例如无法正常工作的灯泡并闪烁。
Chayy 2011年

尝试循环调用this.setAnimation
Jonathan

我当时以为我淡出了当前bg img和fad,但是这个答案激发了我,我只需要淡入当前的bg img和淡出当前的bg img,因为AlphaAnimation不能淡入/淡出两个不同的img。 。
macio.Jun 2014年

8
我认为您不需要具有两个独立的动画...我想您可以具有单个动画并设置参数:fadeInOut.setRepeatMode(Animation.REVERSE);
RoundSparrow hilltx

第二:如果您想重复,则无需像@jonney这样的循环调用。使用fadeInOut.setRepeatCount(6)-将6更改为希望重复的次数。让Android中的本机C ++代码执行所有这些操作而不是在Java循环中进行调用,所需的开销要少得多。
RoundSparrow hilltx

136

我知道这已经被回答了,但是.....

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

快速简单的方法可以自我重复,快速进行淡入和淡出。请享用

编辑:在您的活动中添加以下内容:

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

6
+1因为使用此答案,我可以确保淡入,淡出和淡入(仅设置repeatCount =“ 2”)的安全性。我无法按照已接受的答案建议连接动画。
ElYeante 2014年

1
声明此alpha资源后,我该如何使用它?谢谢
zozelfelfo 2014年

1
zozelfelfo它只是一个动画xml,因此将其加载到代码中,然后在您希望它影响的任何视图上调用startAnimation。
Konrad Winkowski 2014年

@KonradWinkowski startAnimation方法需要将Animation对象作为参数!我应该传递给它什么?
艾哈迈德·瓦塔尼

对于那些寻求更完整答案的人:viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out),在res之下的anim文件夹中有一个fade_in_out.xml文件。
克里斯·奈特

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
棉花糖的优雅!
LETs

26

这是我使用AnimatorSet的解决方案,它似乎比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();

我必须使用ObjectAnimator而不是Animation来获得有效的解决方案,因为由于某种原因,每当我启动AlphaAnimation时,它就会运行两次并发生一些奇怪的闪烁。
Andrew Orobator 2015年

优雅的解决方案
Vlad17年

好了,为时已晚,但我认为这可能会在相同的观点再次帮助一些,请清晰动画使用它之前..
Bhavesh Moradiya

21

另一种选择:

无需为fadeInfadeOut定义2个动画。fadeOutfadeIn的逆向。

因此,您可以使用Animation.REVERSE做到这一点,如下所示:

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

然后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

因为我相信XML(用于布局)的功能,所以这与公认的答案是等效的,但纯粹是作为动画资源:

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

fillAfter是淡出留在完成动画后。该interpolator手柄插值动画的,因为你可以猜到。您还可以使用其他类型的插值器,例如线性或超调。

确保在视图上开始动画:

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

@KGCybeX没问题,很高兴我可以提供帮助:)
DarkCygnus

1
非常有帮助,干净。非常适合我。
费尔南多·巴博萨

9

这是我过去淡入/淡出视图的方法,希望对您有所帮助。

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

不知何故,这是唯一包含设置可见性的答案,很好
路加

8

动画集似乎根本无法正常工作。最后,我放弃了并使用Handler类的postDelayed()对动画进行排序。


8

如果您使用Animator制作动画,则可以

动画(目录)-> 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"/>

在java中

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

使动画仅用Java代码淡出的另一种方法是

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

目录中的anim *不是动画师
kosas

4

您还可以使用animationListener,如下所示:

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

0

我真的很喜欢Vitaly Zinchenkos 解决方案,因为它很短。

这是Kotlin的更简短版本,用于简单的淡出

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.