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

Commit 5e25c2c1 authored by Chet Haase's avatar Chet Haase
Browse files

Add ability to automate animated transitions on View show/hide

Change-Id: Id6ff92c8fd06c3f5fb30c41b020b4de4f567154f
parent 6fee4406
Loading
Loading
Loading
Loading
+49 −19
Original line number Diff line number Diff line
@@ -21025,20 +21025,7 @@
 visibility="public"
>
</constructor>
<method name="addTransitionListener"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="listener" type="android.animation.LayoutTransition.TransitionListener">
</parameter>
</method>
<method name="childAdd"
<method name="addChild"
 return="void"
 abstract="false"
 native="false"
@@ -21053,7 +21040,7 @@
<parameter name="child" type="android.view.View">
</parameter>
</method>
<method name="childRemove"
<method name="addTransitionListener"
 return="void"
 abstract="false"
 native="false"
@@ -21063,9 +21050,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.ViewGroup">
</parameter>
<parameter name="child" type="android.view.View">
<parameter name="listener" type="android.animation.LayoutTransition.TransitionListener">
</parameter>
</method>
<method name="getAnimator"
@@ -21144,6 +21129,36 @@
 visibility="public"
>
</method>
<method name="hideChild"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.ViewGroup">
</parameter>
<parameter name="child" type="android.view.View">
</parameter>
</method>
<method name="removeChild"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.ViewGroup">
</parameter>
<parameter name="child" type="android.view.View">
</parameter>
</method>
<method name="removeTransitionListener"
 return="void"
 abstract="false"
@@ -21245,6 +21260,21 @@
<parameter name="delay" type="long">
</parameter>
</method>
<method name="showChild"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.ViewGroup">
</parameter>
<parameter name="child" type="android.view.View">
</parameter>
</method>
<field name="APPEARING"
 type="int"
 transient="false"
@@ -90112,7 +90142,7 @@
 type="float"
 transient="false"
 volatile="false"
 value="0.0010f"
 value="0.001f"
 static="true"
 final="true"
 deprecated="not deprecated"
+50 −20
Original line number Diff line number Diff line
@@ -544,6 +544,9 @@ public class LayoutTransition {
                        mChangingAppearingAnim.clone() :
                        mChangingDisappearingAnim.clone();

                // Cache the animation in case we need to cancel it later
                currentAnimations.put(child, anim);

                // Set the target object for the animation
                anim.setTarget(child);

@@ -553,13 +556,10 @@ public class LayoutTransition {

                // Add a listener to track layout changes on this view. If we don't get a callback,
                // then there's nothing to animate.
                View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
                final View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
                    public void onLayoutChange(View v, int left, int top, int right, int bottom,
                            int oldLeft, int oldTop, int oldRight, int oldBottom) {

                        // Cache the animation in case we need to cancel it later
                        currentAnimations.put(child, anim);

                        // Tell the animation to extract end values from the changed object
                        anim.setupEndValues();

@@ -577,12 +577,25 @@ public class LayoutTransition {
                        anim.setStartDelay(startDelay);
                        anim.setDuration(duration);

                        if (anim instanceof ObjectAnimator) {
                            ((ObjectAnimator) anim).setCurrentPlayTime(0);
                        }
                        anim.start();

                        // this only removes listeners whose views changed - must clear the
                        // other listeners later
                        child.removeOnLayoutChangeListener(this);
                        layoutChangeListenerMap.remove(child);
                    }
                };
                // Remove the animation from the cache when it ends
                anim.addListener(new AnimatorListenerAdapter() {
                    private boolean canceled = false;
                    public void onAnimationCancel(Animator animator) {
                        // we remove canceled animations immediately, not here
                        canceled = true;
                        child.removeOnLayoutChangeListener(listener);
                        layoutChangeListenerMap.remove(child);
                    }
                    public void onAnimationEnd(Animator animator) {
                        if (!canceled) {
@@ -590,17 +603,7 @@ public class LayoutTransition {
                        }
                    }
                });
                        if (anim instanceof ObjectAnimator) {
                            ((ObjectAnimator) anim).setCurrentPlayTime(0);
                        }
                        anim.start();

                        // this only removes listeners whose views changed - must clear the
                        // other listeners later
                        child.removeOnLayoutChangeListener(this);
                        layoutChangeListenerMap.remove(child);
                    }
                };
                child.addOnLayoutChangeListener(listener);
                // cache the listener for later removal
                layoutChangeListenerMap.put(child, listener);
@@ -662,7 +665,8 @@ public class LayoutTransition {
        anim.setTarget(child);
        if (mListeners != null) {
            anim.addListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd() {
                @Override
                public void onAnimationEnd(Animator anim) {
                    for (TransitionListener listener : mListeners) {
                        listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                    }
@@ -684,7 +688,7 @@ public class LayoutTransition {
     * @param parent The ViewGroup to which the View is being added.
     * @param child The View being added to the ViewGroup.
     */
    public void childAdd(ViewGroup parent, View child) {
    public void addChild(ViewGroup parent, View child) {
        if (mListeners != null) {
            for (TransitionListener listener : mListeners) {
                listener.startTransition(this, parent, child, APPEARING);
@@ -694,6 +698,19 @@ public class LayoutTransition {
        runAppearingTransition(parent, child);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be added to the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup to which the View is being added.
     * @param child The View being added to the ViewGroup.
     */
    public void showChild(ViewGroup parent, View child) {
        addChild(parent, child);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be removed from the
     * container. This callback starts the process of a transition; we grab the starting
@@ -703,7 +720,7 @@ public class LayoutTransition {
     * @param parent The ViewGroup from which the View is being removed.
     * @param child The View being removed from the ViewGroup.
     */
    public void childRemove(ViewGroup parent, View child) {
    public void removeChild(ViewGroup parent, View child) {
        if (mListeners != null) {
            for (TransitionListener listener : mListeners) {
                listener.startTransition(this, parent, child, DISAPPEARING);
@@ -713,6 +730,19 @@ public class LayoutTransition {
        runDisappearingTransition(parent, child);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be removed from the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup from which the View is being removed.
     * @param child The View being removed from the ViewGroup.
     */
    public void hideChild(ViewGroup parent, View child) {
        removeChild(parent, child);
    }

    /**
     * Add a listener that will be called when the bounds of the view change due to
     * layout processing.
+3 −0
Original line number Diff line number Diff line
@@ -4905,6 +4905,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        }

        if ((changed & VISIBILITY_MASK) != 0) {
            if (mParent instanceof ViewGroup) {
                ((ViewGroup)mParent).onChildVisibilityChanged(this, (flags & VISIBILITY_MASK));
            }
            dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
        }

+45 −10
Original line number Diff line number Diff line
@@ -323,6 +323,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    // being animated.
    private ArrayList<View> mTransitioningViews;

    // List of children changing visibility. This is used to potentially keep rendering
    // views during a transition when they otherwise would have become gone/invisible
    private ArrayList<View> mVisibilityChangingChildren;

    public ViewGroup(Context context) {
        super(context);
        initViewGroup();
@@ -757,6 +761,32 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }
    }

    /**
     * @hide
     * @param child
     * @param visibility
     */
    void onChildVisibilityChanged(View child, int visibility) {
        if (mTransition != null) {
            if (visibility == VISIBLE) {
                mTransition.showChild(this, child);
            } else {
                mTransition.hideChild(this, child);
            }
            if (visibility != VISIBLE) {
                // Only track this on disappearing views - appearing views are already visible
                // and don't need special handling during drawChild()
                if (mVisibilityChangingChildren == null) {
                    mVisibilityChangingChildren = new ArrayList<View>();
                }
                mVisibilityChangingChildren.add(child);
                if (mTransitioningViews != null && mTransitioningViews.contains(child)) {
                    addDisappearingView(child);
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
@@ -2598,7 +2628,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }

        if (mTransition != null) {
            mTransition.childAdd(this, child);
            mTransition.addChild(this, child);
        }

        if (!checkLayoutParams(params)) {
@@ -2817,7 +2847,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    private void removeViewInternal(int index, View view) {

        if (mTransition != null) {
            mTransition.childRemove(this, view);
            mTransition.removeChild(this, view);
        }

        boolean clearChildFocus = false;
@@ -2893,7 +2923,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            final View view = children[i];

            if (mTransition != null) {
                mTransition.childRemove(this, view);
                mTransition.removeChild(this, view);
            }

            if (view == focused) {
@@ -2962,7 +2992,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            final View view = children[i];

            if (mTransition != null) {
                mTransition.childRemove(this, view);
                mTransition.removeChild(this, view);
            }

            if (view == focused) {
@@ -3005,7 +3035,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     */
    protected void removeDetachedView(View child, boolean animate) {
        if (mTransition != null) {
            mTransition.childRemove(this, child);
            mTransition.removeChild(this, child);
        }

        if (child == mFocused) {
@@ -4025,12 +4055,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            final ArrayList<View> disappearingChildren = mDisappearingChildren;
            if (disappearingChildren != null && disappearingChildren.contains(view)) {
                disappearingChildren.remove(view);
                if (mVisibilityChangingChildren != null &&
                        mVisibilityChangingChildren.contains(view)) {
                    mVisibilityChangingChildren.remove(view);
                } else {
                    if (view.mAttachInfo != null) {
                        view.dispatchDetachedFromWindow();
                    }
                    if (view.mParent != null) {
                        view.mParent = null;
                    }
                }
                mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
            }
        }
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public interface Adapter {
    long getItemId(int position);
    
    /**
     * Indicated whether the item ids are stable across changes to the
     * Indicates whether the item ids are stable across changes to the
     * underlying data.
     * 
     * @return True if the same id always refers to the same object.
Loading