我有一个AnimationDrawable,它播放一个帧动画,然后下一个Activity以圆形显示动画开始:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
AnimationDrawable animationDrawable =
(AnimationDrawable) mAnimationSceneImage.getDrawable();
animationDrawable.start();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startMapActivityWithAnimation();
}
}, 1000);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void startMapActivityWithAnimation() {
int colorFrom = ContextCompat.getColor(this, R.color.window_background_splash);
int colorTo = ContextCompat.getColor(this, android.R.color.white);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCircularRevealView.setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
}
});
int cx = mCircularRevealView.getWidth() / 2;
int cy = mCircularRevealView.getHeight() / 2;
float finalRadius = Math.max(cx, cy);
Animator circularRevealAnimation = ViewAnimationUtils
.createCircularReveal(mCircularRevealView, cx, cy, 0, finalRadius);
mCircularRevealView.setVisibility(View.VISIBLE);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(200);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mLogoImage.animate()
.alpha(0.0f)
.setDuration(200)
.setInterpolator(new AccelerateInterpolator())
.start();
}
@Override
public void onAnimationEnd(Animator animation) {
startMapActivity();
}
});
animatorSet.playTogether(colorAnimation, circularRevealAnimation);
animatorSet.start();
}
动画在普通设备上运行完美。我也有一些Espresso UI测试,所以我已经在测试设备的开发者选项屏幕上禁用了所有动画,现在我得到以下例外:
java.lang.IllegalStateException: Animator has already started, cannot change it now!
at android.view.RenderNodeAnimator.checkMutable(RenderNodeAnimator.java:149)
at android.view.RenderNodeAnimator.setDuration(RenderNodeAnimator.java:324)
at android.view.RenderNodeAnimator.setDuration(RenderNodeAnimator.java:322)
at android.animation.AnimatorSet.updateAnimatorsDuration(AnimatorSet.java:760)
at android.animation.AnimatorSet.getTotalDuration(AnimatorSet.java:1721)
at android.animation.AnimatorSet.forceToEnd(AnimatorSet.java:446)
at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:981)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:145)
at android.animation.AnimationHandler.-wrap2(Unknown Source:0)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:884)
at android.view.Choreographer.doCallbacks(Choreographer.java:698)
at android.view.Choreographer.doFrame(Choreographer.java:630)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:872)
at android.os.Handler.handleCallback(Handler.java:769)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6540)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
您对如何解决此问题有任何建议吗?
答案 0 :(得分:3)
我遇到了同样的问题,我已经解决了。您不能在类AnimatorSet中使用方法setDuration,它可能会在设备8.0上导致此问题。您可以在每个Animator中使用方法setDuration。
private void startMapActivityWithAnimation() {
int colorFrom = ContextCompat.getColor(this, R.color.window_background_splash);
int colorTo = ContextCompat.getColor(this, android.R.color.white);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(200);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCircularRevealView.setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
}
});
int cx = mCircularRevealView.getWidth() / 2;
int cy = mCircularRevealView.getHeight() / 2;
float finalRadius = Math.max(cx, cy);
Animator circularRevealAnimation = ViewAnimationUtils
.createCircularReveal(mCircularRevealView, cx, cy, 0, finalRadius);
circularRevealAnimation.setDuration(200);
mCircularRevealView.setVisibility(View.VISIBLE);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mLogoImage.animate()
.alpha(0.0f)
.setDuration(200)
.setInterpolator(new AccelerateInterpolator())
.start();
}
@Override
public void onAnimationEnd(Animator animation) {
startMapActivity();
}
});
animatorSet.playTogether(colorAnimation, circularRevealAnimation);
animatorSet.start();
}
答案 1 :(得分:1)
检查动画师是否已经开始了怎么办?
if (!animatorSet.isStarted()) {
animatorSet.start();
}
答案 2 :(得分:1)
您可以在@Before方法中为该特定测试启用动画。测试完成后,您可以在@After方法中再次禁用动画。这样你的后续测试就不会受到影响。 您还可以创建一个测试规则来启用/禁用特定类的动画,如here
所示