淡入淡出 Java 中的 Android 动画

Posted

技术标签:

【中文标题】淡入淡出 Java 中的 Android 动画【英文标题】:Fade In Fade Out Android Animation in Java 【发布时间】:2011-10-11 09:18:37 【问题描述】:

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

这是我的 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 的所有可能组合。 将LinearInterpolator 添加到AnimationSet

【问题讨论】:

是的,您可以淡入淡出图像!本教程应该可以解决问题。 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) 【参考方案1】:

我真的很喜欢Vitaly Zinchenkos solution,因为它很短。

这是一个更简洁的 kotlin 版本,用于简单的淡出

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

【讨论】:

【参考方案2】:

想出了我自己的问题。该解决方案最终基于插值器。

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)

【讨论】:

如果你想做 5 或 6 次淡入/淡出,每个延迟非常小,比如 100,你能用这样的东西吗?我试过了,但不是很流畅。目的是模拟一个无法正常工作并闪烁的灯泡。 尝试循环调用 this.setAnimation 我在想我淡出最后一个 bg img 并淡入当前一个,但这个答案启发我,我只需要淡入当前 bg img 并淡出当前一个,因为 AlphaAnimation 可以'不淡入/淡出两个不同的图像。 我认为你不需要有两个独立的动画...我认为你可以有一个动画并设置参数:fadeInOut.setRepeatMode(Animation.REVERSE); 第二:如果你想重复,不需要像@jonney说的那样循环调用。使用 fadeInOut.setRepeatCount(6) - 将 6 更改为您希望它重复的次数。让 Android 中的原生 C++ 代码完成所有这些操作,而不是在 Java 循环中调用,开销要少得多。【参考方案3】:

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

anim(目录)-> 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* 不是 animator @LeTadas 在目录动画师中,根据 Android Studio android:duration="1000"【参考方案4】:

我相信 XML 的力量(用于布局),这相当于公认的 answer,但纯粹是作为动画资源:

<?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 处理动画的interpolation,你可以猜到。您还可以使用其他类型的插值器,例如线性或过冲。

一定要在你的视图上开始你的动画:

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

【讨论】:

@KGCybeX 没问题,很高兴我能帮上忙 :) 非常有帮助和干净。非常适合我。【参考方案5】:

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

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

【讨论】:

+1 因为有了这个答案,我可以制作一个淡入、淡出和淡入的序列(只需设置 repeatCount="2")。我无法按照接受的答案建议连接动画。 在声明了这个alpha 资源后我该如何使用它?谢谢 zozelfelfo 它只是一个动画 xml,因此将其加载到代码中,然后在您希望它影响的任何视图上调用 startAnimation。 @KonradWinkowski startAnimation 方法需要动画对象作为参数!我应该传递给它什么? 对于那些寻找更完整答案的人:viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out),其中 res 下的 anim 文件夹中有一个 fade_in_out.xml 文件。【参考方案6】:

另一种选择:

不需要为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
        
    );

【讨论】:

【参考方案7】:

这是我用来淡入/淡出视图的内容,希望对某人有所帮助。

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

【讨论】:

棉花糖的优雅! 需要注意的重要一点是,如果在第二个动画中使用setStartDelay()来延迟它的启动,则需要在第一个动画中将setStartDelay()重置为0。否则它会记住任何后续动画的延迟。【参考方案9】:

你也可以使用animationListener,像这样:

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

【讨论】:

【参考方案10】:

这是我使用 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 时,它都会运行两次并出现一些奇怪的闪烁。 优雅的解决方案 好吧,为时已晚,但我认为这可能会有所帮助,请在同一视图上再次使用之前清除动画..【参考方案11】:

AnimationSet 似乎根本没有按预期工作。最后我放弃了,使用 Handler 类的 postDelayed() 对动画进行排序。

【讨论】:

以上是关于淡入淡出 Java 中的 Android 动画的主要内容,如果未能解决你的问题,请参考以下文章

Android使用淡入/淡出动画更改背景图像

Android - 如何使用交叉淡入淡出动画更改状态栏颜色[重复]

Android属性动画小练习(简单实现旋转平移淡入淡出缩放动画效果)

如何在 Activity 过渡上执行淡入淡出动画?

可以在 Ionic 2 中的图像之间制作淡入淡出动画

Android 使用 ImageView 淡入淡出