淡入淡出 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 动画时,行为会按预期工作。
我已经尝试过的事情:
setFillBefore
、setFillAfter
和 setFillEnabled
的所有可能组合。
将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 Studioandroid: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(context, 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(context, 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】:
另一种选择:
不需要为fadeIn和fadeOut定义2个动画。 fadeOut 是 fadeIn 的反面。
所以你可以像这样使用 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 - 如何使用交叉淡入淡出动画更改状态栏颜色[重复]