summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2016-10-27 17:54:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-10-27 17:55:03 +0000
commit09c7a38755b43058c8cdf2ee35a3e466b1f302f8 (patch)
tree04142fa431572bb76f08562b1b52ace92b8cdfc6
parenteb1501ac3f02f6ca45c2ddcfad782bc5af2e442c (diff)
parent4fe47117606d39e9b7ab5a7fbf5b0dce753c83ba (diff)
Merge "Fix hide fragment transition"
-rw-r--r--core/java/android/app/Fragment.java15
-rw-r--r--core/java/android/app/FragmentManager.java31
-rw-r--r--core/java/android/app/FragmentTransition.java33
3 files changed, 66 insertions, 13 deletions
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 5d1cd3ba8a9c..8124232bd49e 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2849,6 +2849,17 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
return mAnimationInfo.mEnterTransitionPostponed;
}
+ boolean isHideReplaced() {
+ if (mAnimationInfo == null) {
+ return false;
+ }
+ return mAnimationInfo.mIsHideReplaced;
+ }
+
+ void setHideReplaced(boolean replaced) {
+ ensureAnimationInfo().mIsHideReplaced = replaced;
+ }
+
/**
* Used internally to be notified when {@link #startPostponedEnterTransition()} has
* been called. This listener will only be called once and then be removed from the
@@ -2902,7 +2913,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// be set to null
OnStartEnterTransitionListener mStartEnterTransitionListener;
- // True if the View was added, and its animation has yet to be run.
- boolean mIsNewlyAdded;
+ // True if the View was hidden, but the transition is handling the hide
+ boolean mIsHideReplaced;
}
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9345a03bb2f2..233fee73f601 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1185,23 +1185,32 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
if (anim != null) {
anim.setTarget(fragment.mView);
if (fragment.mHidden) {
- // Delay the actual hide operation until the animation finishes, otherwise
- // the fragment will just immediately disappear
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- animation.removeListener(this);
- if (fragment.mView != null) {
- fragment.mView.setVisibility(View.GONE);
+ if (fragment.isHideReplaced()) {
+ fragment.setHideReplaced(false);
+ } else {
+ // Delay the actual hide operation until the animation finishes, otherwise
+ // the fragment will just immediately disappear
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ animation.removeListener(this);
+ if (fragment.mView != null) {
+ fragment.mView.setVisibility(View.GONE);
+ }
}
- }
- });
+ });
+ }
}
setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
anim.start();
} else {
- final int visibility = fragment.mHidden ? View.GONE : View.VISIBLE;
+ final int visibility = fragment.mHidden && !fragment.isHideReplaced()
+ ? View.GONE
+ : View.VISIBLE;
fragment.mView.setVisibility(visibility);
+ if (fragment.isHideReplaced()) {
+ fragment.setHideReplaced(false);
+ }
}
}
if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 6f5211468b13..d27dff5e2227 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -222,6 +222,7 @@ class FragmentTransition {
sharedElementTransition, inFragment, inIsPop);
if (transition != null) {
+ replaceHide(exitTransition, outFragment, exitingViews);
transition.setNameOverrides(nameOverrides);
scheduleRemoveTargets(transition,
enterTransition, enteringViews, exitTransition, exitingViews,
@@ -309,6 +310,38 @@ class FragmentTransition {
}
/**
+ * Replace hide operations with visibility changes on the exiting views. Instead of making
+ * the entire fragment's view GONE, make each exiting view INVISIBLE. At the end of the
+ * transition, make the fragment's view GONE.
+ */
+ private static void replaceHide(Transition exitTransition, Fragment exitingFragment,
+ final ArrayList<View> exitingViews) {
+ if (exitingFragment != null && exitTransition != null && exitingFragment.mAdded
+ && exitingFragment.mHidden && exitingFragment.mHiddenChanged) {
+ exitingFragment.setHideReplaced(true);
+ final View fragmentView = exitingFragment.getView();
+ final ViewGroup container = exitingFragment.mContainer;
+ container.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ container.getViewTreeObserver().removeOnPreDrawListener(this);
+ setViewVisibility(exitingViews, View.INVISIBLE);
+ return true;
+ }
+ });
+ exitTransition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transition.removeListener(this);
+ fragmentView.setVisibility(View.GONE);
+ setViewVisibility(exitingViews, View.VISIBLE);
+ }
+ });
+ }
+ }
+
+ /**
* This method is used for fragment transitions for unoptimized transactions to change the
* enter and exit transition targets after the call to
* {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)}. The exit transition