Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5976d24d authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Make fragment animations work when fragments go away"

parents 28d8fda9 b20db3ec
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -202631,6 +202631,19 @@
<parameter name="drawingTime" type="long">
</parameter>
</method>
<method name="endViewTransition"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="view" type="android.view.View">
</parameter>
</method>
<method name="focusSearch"
 return="android.view.View"
 abstract="false"
@@ -203528,6 +203541,19 @@
 visibility="public"
>
</method>
<method name="startViewTransition"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="view" type="android.view.View">
</parameter>
</method>
<method name="updateViewLayout"
 return="void"
 abstract="false"
+10 −1
Original line number Diff line number Diff line
@@ -686,6 +686,13 @@ public class ValueAnimator<T> extends Animator {
    private void start(boolean playBackwards) {
        mPlayingBackwards = playBackwards;
        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
            if (mListeners != null) {
                ArrayList<AnimatorListener> tmpListeners =
                        (ArrayList<AnimatorListener>) mListeners.clone();
                for (AnimatorListener listener : tmpListeners) {
                    listener.onAnimationStart(this);
                }
            }
            // This sets the initial value of the animation, prior to actually starting it running
            setCurrentPlayTime(getCurrentPlayTime());
        }
@@ -783,7 +790,9 @@ public class ValueAnimator<T> extends Animator {
    private void startAnimation() {
        initAnimation();
        sAnimations.add(this);
        if (mListeners != null) {
        if (mStartDelay > 0 && mListeners != null) {
            // Listeners were already notified in start() if startDelay is 0; this is
            // just for delayed animations
            ArrayList<AnimatorListener> tmpListeners =
                    (ArrayList<AnimatorListener>) mListeners.clone();
            for (AnimatorListener listener : tmpListeners) {
+19 −25
Original line number Diff line number Diff line
@@ -18,8 +18,7 @@ package android.app;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.AnimatorListenerAdapter;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
@@ -363,11 +362,7 @@ final class FragmentManagerImpl implements FragmentManager {
                                    Animator anim = loadAnimator(f, transit, true,
                                            transitionStyle);
                                    if (anim != null) {
                                        if (anim instanceof AnimatorSet) {
                                            ((AnimatorSet)anim).setTarget(f.mView);
                                        } else if (anim instanceof ObjectAnimator) {
                                            ((ObjectAnimator)anim).setTarget(f.mView);
                                        }
                                        anim.setTarget(f.mView);
                                        anim.start();
                                    }
                                    container.addView(f.mView);
@@ -447,17 +442,24 @@ final class FragmentManagerImpl implements FragmentManager {
                                    + " did not call through to super.onDestroyedView()");
                        }
                        if (f.mView != null && f.mContainer != null) {
                            Animator anim = null;
                            if (mCurState > Fragment.INITIALIZING) {
                                Animator anim = loadAnimator(f, transit, true,
                                anim = loadAnimator(f, transit, false,
                                        transitionStyle);
                            }
                            if (anim != null) {
                                    if (anim instanceof AnimatorSet) {
                                        ((AnimatorSet)anim).setTarget(f.mView);
                                    } else if (anim instanceof ObjectAnimator) {
                                        ((ObjectAnimator)anim).setTarget(f.mView);
                                final ViewGroup container = f.mContainer;
                                final View view = f.mView;
                                container.startViewTransition(view);
                                anim.addListener(new AnimatorListenerAdapter() {
                                    @Override
                                    public void onAnimationEnd(Animator anim) {
                                        container.endViewTransition(view);
                                    }
                                });
                                anim.setTarget(f.mView);
                                anim.start();
                                }

                            }
                            f.mContainer.removeView(f.mView);
                        }
@@ -591,11 +593,7 @@ final class FragmentManagerImpl implements FragmentManager {
                Animator anim = loadAnimator(fragment, transition, true,
                        transitionStyle);
                if (anim != null) {
                    if (anim instanceof AnimatorSet) {
                        ((AnimatorSet)anim).setTarget(fragment.mView);
                    } else if (anim instanceof ObjectAnimator) {
                        ((ObjectAnimator)anim).setTarget(fragment.mView);
                    }
                    anim.setTarget(fragment.mView);
                    anim.start();
                }
                fragment.mView.setVisibility(View.GONE);
@@ -615,11 +613,7 @@ final class FragmentManagerImpl implements FragmentManager {
                Animator anim = loadAnimator(fragment, transition, true,
                        transitionStyle);
                if (anim != null) {
                    if (anim instanceof AnimatorSet) {
                        ((AnimatorSet)anim).setTarget(fragment.mView);
                    } else if (anim instanceof ObjectAnimator) {
                        ((ObjectAnimator)anim).setTarget(fragment.mView);
                    }
                    anim.setTarget(fragment.mView);
                    anim.start();
                }
                fragment.mView.setVisibility(View.VISIBLE);
+53 −16
Original line number Diff line number Diff line
@@ -2603,6 +2603,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
     */
    public void setLayoutTransition(LayoutTransition transition) {
        if (mTransition != null) {
            mTransition.removeTransitionListener(mLayoutTransitionListener);
        }
        mTransition = transition;
        if (mTransition != null) {
            mTransition.addTransitionListener(mLayoutTransitionListener);
@@ -3731,14 +3734,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }
    }

    private LayoutTransition.TransitionListener mLayoutTransitionListener =
            new LayoutTransition.TransitionListener() {
        @Override
        public void startTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType) {
            // We only care about disappearing items, since we need special logic to keep
            // those items visible after they've been 'removed'
            if (transitionType == LayoutTransition.DISAPPEARING) {
    /**
     * This method tells the ViewGroup that the given View object, which should have this
     * ViewGroup as its parent,
     * should be kept around  (re-displayed when the ViewGroup draws its children) even if it
     * is removed from its parent. This allows animations, such as those used by
     * {@link android.app.Fragment} and {@link android.animation.LayoutTransition} to animate
     * the removal of views. A call to this method should always be accompanied by a later call
     * to {@link #endViewTransition(View)}, such as after an animation on the View has finished,
     * so that the View finally gets removed.
     *
     * @param view The View object to be kept visible even if it gets removed from its parent.
     */
    public void startViewTransition(View view) {
        if (view.mParent == this) {
            if (mTransitioningViews == null) {
                mTransitioningViews = new ArrayList<View>();
            }
@@ -3746,10 +3755,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }
    }

        @Override
        public void endTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType) {
            if (transitionType == LayoutTransition.DISAPPEARING && mTransitioningViews != null) {
    /**
     * This method should always be called following an earlier call to
     * {@link #startViewTransition(View)}. The given View is finally removed from its parent
     * and will no longer be displayed. Note that this method does not perform the functionality
     * of removing a view from its parent; it just discontinues the display of a View that
     * has previously been removed.
     *
     * @return view The View object that has been removed but is being kept around in the visible
     * hierarchy by an earlier call to {@link #startViewTransition(View)}.
     */
    public void endViewTransition(View view) {
        if (mTransitioningViews != null) {
            mTransitioningViews.remove(view);
            final ArrayList<View> disappearingChildren = mDisappearingChildren;
            if (disappearingChildren != null && disappearingChildren.contains(view)) {
@@ -3764,6 +3781,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            }
        }
    }

    private LayoutTransition.TransitionListener mLayoutTransitionListener =
            new LayoutTransition.TransitionListener() {
        @Override
        public void startTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType) {
            // We only care about disappearing items, since we need special logic to keep
            // those items visible after they've been 'removed'
            if (transitionType == LayoutTransition.DISAPPEARING) {
                startViewTransition(view);
            }
        }

        @Override
        public void endTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType) {
            if (transitionType == LayoutTransition.DISAPPEARING && mTransitioningViews != null) {
                endViewTransition(view);
            }
        }
    };

    /**