我创建了一个自定义循环显示过渡,用作Activity的输入过渡的一部分(具体来说,我通过调用Window#setEnterTransition()
将过渡设置为窗口的输入过渡):
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;
}
}
这通常正常。但是,当我在转换过程中单击“后退按钮”时,我得到以下异常:
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)
我收到此错误有什么具体原因吗?应该如何避免?
答案 0 :(得分:10)
您需要创建Animator
的子类,忽略对pause()
和resume()
的调用,以避免此异常。
有关详细信息,我刚刚完成了有关此主题的帖子:
答案 1 :(得分:3)
我收到此错误有什么具体原因吗?
ViewAnimationUtils.createCircularReveal
是创建新RevealAnimator
的快捷方式,RenderNodeAnimator.pause
是RenderNodeAnimator
的子类。默认情况下,Activity.finishAfterTransition
会抛出UnsupportedOperationException
。您会在堆栈跟踪中看到这种情况:
java.lang.UnsupportedOperationException
at android.view.RenderNodeAnimator.pause(RenderNodeAnimator.java:251)
在Lollipop中调用Activity.onBackPressed
后,它会对Transition.pause(android.view.View)
进行新的调用,最终会在EnterTransitionCoordinator
handles the entering Transition
once it's completed.中回拨Animator.pause
,这时候就是{ {1}}终于被抛出了。
转换完成后使用“后退”按钮时未抛出的原因是TransitionListener
应该如何避免?
我想你有几个选择,但两者都不是很理想:
选项1
致电UnsupportedOperationException
时附加ActivityTransitionState.clear
,以便您可以监控何时调用“后退”按钮。所以,像:
Window.setEnterTransition
选项2
使用反射来调用ActivityTransitionState.startExitBackTransition
,这将阻止在Here's a gfy of the results.中调用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();
}
}
}
。
Transition.pause(android.view.View)
显然每个都有缺点。选项1基本上禁用“后退”按钮,直到转换完成。选项2允许您使用“后退”按钮进行中断,但会清除过渡状态并使用反射。
{{3}}你可以看到它是如何从“A”完全转换到“M”再返回,然后“后退”按钮会中断转换并返回“A”。如果你观看它会更有意义。
无论如何,我希望能帮到你一些。
答案 2 :(得分:0)
您可以添加侦听器以输入在方法transitionInProgress
/ onTransitionStart()
中设置标记onTransitionEnd()
的转换。然后,您可以覆盖方法finishAfterTransition()
,然后检查transitionInProgress
标记,并仅在转换完成时调用super
。否则,您只能finish()
Activity
或无所事事。
override fun finishAfterTransition() {
if (!transitionInProgress){
super.finishAfterTransition()
} else {
finish()
}
}