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

Commit b20db3ec authored by Chet Haase's avatar Chet Haase
Browse files

Make fragment animations work when fragments go away

Change-Id: I136de6ef910cc02b8181fcfa065bdb0770841396
parent 547705d3
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);
            }
        }
    };

    /**