自定义循环显示过渡结果在“java.lang.UnsupportedOperationException”暂停?

我创build了一个自定义的圆形显示转换,作为一个Activity的input转换的一部分(具体来说,我通过调用Window#setEnterTransition()设置转换为窗口的input转换):

 public class CircularRevealTransition extends Visibility { private final Rect mStartBounds = new Rect(); /** * Use the view's location as the circular reveal's starting position. */ public CircularRevealTransition(View v) { int[] loc = new int[2]; v.getLocationInWindow(loc); mStartBounds.set(loc[0], loc[1], loc[0] + v.getWidth(), loc[1] + v.getHeight()); } @Override public Animator onAppear(ViewGroup sceneRoot, final View v, TransitionValues startValues, TransitionValues endValues) { if (endValues == null) { return null; } int halfWidth = v.getWidth() / 2; int halfHeight = v.getHeight() / 2; float startX = mStartBounds.left + mStartBounds.width() / 2 - halfWidth; float startY = mStartBounds.top + mStartBounds.height() / 2 - halfHeight; float endX = v.getTranslationX(); float endY = v.getTranslationY(); v.setTranslationX(startX); v.setTranslationY(startY); // Create a circular reveal animator to play behind a shared // element during the Activity Transition. Animator revealAnimator = ViewAnimationUtils.createCircularReveal(v, halfWidth, halfHeight, 0f, FloatMath.sqrt(halfWidth * halfHeight + halfHeight * halfHeight)); revealAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // Set the view's visibility to VISIBLE to prevent the // reveal from "blinking" at the end of the animation. v.setVisibility(View.VISIBLE); } }); // Translate the circular reveal into place as it animates. PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX", startX, endX); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY", startY, endY); Animator translationAnimator = ObjectAnimator.ofPropertyValuesHolder(v, pvhX, pvhY); AnimatorSet anim = new AnimatorSet(); anim.setInterpolator(getInterpolator()); anim.playTogether(revealAnimator, translationAnimator); return anim; } } 

这通常工作正常。 但是,当我单击转换中间的“后退button”时,出现以下exception:

 Process: com.adp.activity.transitions, PID: 13800 java.lang.UnsupportedOperationException at android.view.RenderNodeAnimator.pause(RenderNodeAnimator.java:251) at android.animation.AnimatorSet.pause(AnimatorSet.java:472) at android.transition.Transition.pause(Transition.java:1671) at android.transition.TransitionSet.pause(TransitionSet.java:483) at android.app.ActivityTransitionState.startExitBackTransition(ActivityTransitionState.java:269) at android.app.Activity.finishAfterTransition(Activity.java:4672) at com.adp.activity.transitions.DetailsActivity.finishAfterTransition(DetailsActivity.java:167) at android.app.Activity.onBackPressed(Activity.java:2480) 

有什么具体的原因,我得到这个错误? 应该如何避免?

Solutions Collecting From Web of "自定义循环显示过渡结果在“java.lang.UnsupportedOperationException”暂停?"

您将需要创buildAnimator的子类,以忽略对pause()resume()调用,以避免此exception。

有关更多详情,我刚刚完成了关于此主题的一篇文章:

  • 第1部分: http : //halfthought.wordpress.com/2014/11/07/reveal-transition/
  • 第2部分: https : //halfthought.wordpress.com/2014/12/02/reveal-activity-transitions/

有什么具体的原因,我得到这个错误?

ViewAnimationUtils.createCircularReveal是创build一个新的RevealAnimator的快捷方式,它是RenderNodeAnimator一个子类。 默认情况下, RenderNodeAnimator.pause抛出一个UnsupportedOperationExceptionexception。 你看到这发生在你的堆栈跟踪中:

 java.lang.UnsupportedOperationException at android.view.RenderNodeAnimator.pause(RenderNodeAnimator.java:251) 

当在Lollipop中调用Activity.finishAfterTransition ,它将对Activity.finishAfterTransition进行一个新的调用,最终在Transition.pause(android.view.View)调用Animator.pause ,最后抛出UnsupportedOperationExceptionexception。

在转换完成后使用“后退”button时不会抛出的原因是由于EnterTransitionCoordinator在完成后如何处理input的Transition

应该如何避免?

我想你有几个select,但都不是很理想:

选项1

在调用Window.setEnterTransition时附加一个TransitionListener ,以便监视何时调用“返回”button。 所以,像这样的:

 public class YourActivity extends Activity { /** True if the current window transition is animating, false otherwise */ private boolean mIsAnimating = true; @Override protected void onCreate(Bundle savedInstanceState) { // Get the Window and enable Activity transitions final Window window = getWindow(); window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // Call through to super super.onCreate(savedInstanceState); setContentView(R.layout.activity_child); // Set the window transition and attach our listener final Transition circularReveal = new CircularRevealTransition(yourView); window.setEnterTransition(circularReveal.addListener(new TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { super.onTransitionEnd(transition); mIsAnimating = false; } })); // Restore the transition state if available if (savedInstanceState != null) { mIsAnimating = savedInstanceState.getBoolean("key"); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save the current transition state outState.putBoolean("key", mIsAnimating); } @Override public void onBackPressed() { if (!mIsAnimating) { super.onBackPressed(); } } } 

选项2

使用reflection来调用ActivityTransitionState.clear ,这将停止在ActivityTransitionState.startExitBackTransition中调用Transition.pause(android.view.View)

 @Override public void onBackPressed() { if (!mIsAnimating) { super.onBackPressed(); } else { clearTransitionState(); super.onBackPressed(); } } private void clearTransitionState() { try { // Get the ActivityTransitionState Field final Field atsf = Activity.class.getDeclaredField("mActivityTransitionState"); atsf.setAccessible(true); // Get the ActivityTransitionState final Object ats = atsf.get(this); // Invoke the ActivityTransitionState.clear Method final Method clear = ats.getClass().getDeclaredMethod("clear", (Class[]) null); clear.invoke(ats); } catch (final Exception ignored) { // Nothing to do } } 

显然每个人都有缺点。 选项1基本上禁用“返回”button,直到转换完成。 选项2允许您使用“返回”button中断,但清除过渡状态并使用reflection。

这是一个结果gfy。 您可以看到它是如何从“A”完全转换到“M”的,然后再回到“后退”button中断转换并返回到“A”。 如果你看,这会更有意义。

无论如何,我希望能帮助你一些。

您可以添加侦听器来input在onTransitionStart() / onTransitionEnd()方法中设置标志transitionInProgress 。 然后,您可以重写方法finishAfterTransition() ,然后检查transitionInProgress标志,并且只有在转换完成时才调用super 。 否则,你可以finish()你的Activity或什么都不做。

 override fun finishAfterTransition() { if (!transitionInProgress){ super.finishAfterTransition() } else { finish() } }