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

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

Merge "Make fading transitions work better" into klp-dev

parents adf14902 b7a7fc9d
Loading
Loading
Loading
Loading
+38 −16
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ import java.util.Map;
 *
 * @hide
 */
public class TextChange extends Transition {
public class ChangeText extends Transition {

    private static final String LOG_TAG = "TextChange";

@@ -103,7 +103,7 @@ public class TextChange extends Transition {
     * transition is run.
     * @return this textChange object.
     */
    public TextChange setChangeBehavior(int changeBehavior) {
    public ChangeText setChangeBehavior(int changeBehavior) {
        if (changeBehavior >= CHANGE_BEHAVIOR_KEEP && changeBehavior <= CHANGE_BEHAVIOR_OUT_IN) {
            mChangeBehavior = changeBehavior;
        }
@@ -179,10 +179,14 @@ public class TextChange extends Transition {
            startSelectionStart = startSelectionEnd = endSelectionStart = endSelectionEnd = -1;
        }
        if (!startText.equals(endText)) {
            final int startColor = (Integer) startVals.get(PROPNAME_TEXT_COLOR);
            final int endColor = (Integer) endVals.get(PROPNAME_TEXT_COLOR);
            if (mChangeBehavior != CHANGE_BEHAVIOR_IN) {
                view.setText(startText);
                if (view instanceof EditText) {
                    setSelection(((EditText) view), startSelectionStart, startSelectionEnd);
                }
            }
            Animator anim;
            if (mChangeBehavior == CHANGE_BEHAVIOR_KEEP) {
                anim = ValueAnimator.ofFloat(0, 1);
@@ -200,8 +204,6 @@ public class TextChange extends Transition {
                });
            } else {
                // Fade out start text
                final int startColor = (Integer) startVals.get(PROPNAME_TEXT_COLOR);
                final int endColor = (Integer) endVals.get(PROPNAME_TEXT_COLOR);
                ValueAnimator outAnim = null, inAnim = null;
                if (mChangeBehavior == CHANGE_BEHAVIOR_OUT_IN ||
                        mChangeBehavior == CHANGE_BEHAVIOR_OUT) {
@@ -210,8 +212,8 @@ public class TextChange extends Transition {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            int currAlpha = (Integer) animation.getAnimatedValue();
                            view.setTextColor(currAlpha << 24 | Color.red(startColor) << 16 |
                                    Color.green(startColor) << 8 | Color.red(startColor));
                            view.setTextColor(currAlpha << 24 | startColor & 0xff0000 |
                                    startColor & 0xff00 | startColor & 0xff);
                        }
                    });
                    outAnim.addListener(new AnimatorListenerAdapter() {
@@ -225,6 +227,8 @@ public class TextChange extends Transition {
                                            endSelectionEnd);
                                }
                            }
                            // restore opaque alpha and correct end color
                            view.setTextColor(endColor);
                        }
                    });
                }
@@ -239,6 +243,13 @@ public class TextChange extends Transition {
                                    Color.green(endColor) << 8 | Color.red(endColor));
                        }
                    });
                    inAnim.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationCancel(Animator animation) {
                            // restore opaque alpha and correct end color
                            view.setTextColor(endColor);
                        }
                    });
                }
                if (outAnim != null && inAnim != null) {
                    anim = new AnimatorSet();
@@ -251,23 +262,34 @@ public class TextChange extends Transition {
                }
            }
            TransitionListener transitionListener = new TransitionListenerAdapter() {
                boolean mCanceled = false;
                int mPausedColor = 0;

                @Override
                public void onTransitionPause(Transition transition) {
                    if (mChangeBehavior != CHANGE_BEHAVIOR_IN) {
                        view.setText(endText);
                        if (view instanceof EditText) {
                            setSelection(((EditText) view), endSelectionStart, endSelectionEnd);
                        }
                    }
                    if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) {
                        mPausedColor = view.getCurrentTextColor();
                        view.setTextColor(endColor);
                    }
                }

                @Override
                public void onTransitionResume(Transition transition) {
                    if (mChangeBehavior != CHANGE_BEHAVIOR_IN) {
                        view.setText(startText);
                        if (view instanceof EditText) {
                            setSelection(((EditText) view), startSelectionStart, startSelectionEnd);
                        }
                    }
                    if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) {
                        view.setTextColor(mPausedColor);
                    }
                }
            };
            addListener(transitionListener);
            if (DBG) {
+41 −4
Original line number Diff line number Diff line
@@ -30,6 +30,24 @@ import android.view.ViewGroup;
 * {@link View#setVisibility(int)} state of the view as well as whether it
 * is parented in the current view hierarchy.
 *
 * <p>The ability of this transition to fade out a particular view, and the
 * way that that fading operation takes place, is based on
 * the situation of the view in the view hierarchy. For example, if a view was
 * simply removed from its parent, then the view will be added into a {@link
 * android.view.ViewGroupOverlay} while fading. If a visible view is
 * changed to be {@link View#GONE} or {@link View#INVISIBLE}, then the
 * visibility will be changed to {@link View#VISIBLE} for the duration of
 * the animation. However, if a view is in a hierarchy which is also altering
 * its visibility, the situation can be more complicated. In general, if a
 * view that is no longer in the hierarchy in the end scene still has a
 * parent (so its parent hierarchy was removed, but it was not removed from
 * its parent), then it will be left alone to avoid side-effects from
 * improperly removing it from its parent. The only exception to this is if
 * the previous {@link Scene} was
 * {@link Scene#getSceneForLayout(android.view.ViewGroup, int, android.content.Context)
 * created from a layout resource file}, then it is considered safe to un-parent
 * the starting scene view in order to fade it out.</p>
 *
 * <p>A Fade transition can be described in a resource file by using the
 * tag <code>fade</code>, along with the standard
 * attributes of {@link android.R.styleable#Fade} and
@@ -167,7 +185,7 @@ public class Fade extends Visibility {
        if ((mFadingMode & OUT) != OUT) {
            return null;
        }
        View view;
        View view = null;
        View startView = (startValues != null) ? startValues.view : null;
        View endView = (endValues != null) ? endValues.view : null;
        if (DBG) {
@@ -177,9 +195,28 @@ public class Fade extends Visibility {
        View overlayView = null;
        View viewToKeep = null;
        if (endView == null || endView.getParent() == null) {
            // view was removed: add the start view to the Overlay
            view = startView;
            overlayView = view;
            if (endView != null) {
                // endView was removed from its parent - add it to the overlay
                view = overlayView = endView;
            } else if (startView != null) {
                // endView does not exist. Use startView only under certain
                // conditions, because placing a view in an overlay necessitates
                // it being removed from its current parent
                if (startView.getParent() == null) {
                    // no parent - safe to use
                    view = overlayView = startView;
                } else if (startView.getParent() instanceof View &&
                        startView.getParent().getParent() == null) {
                    View startParent = (View) startView.getParent();
                    int id = startParent.getId();
                    if (id != View.NO_ID && sceneRoot.findViewById(id) != null && mCanRemoveViews) {
                        // no parent, but its parent is unparented  but the parent
                        // hierarchy has been replaced by a new hierarchy with the same id
                        // and it is safe to un-parent startView
                        view = overlayView = startView;
                    }
                }
            }
        } else {
            // visibility change
            if (endVisibility == View.INVISIBLE) {
+17 −2
Original line number Diff line number Diff line
@@ -157,11 +157,11 @@ public final class Scene {
    public void enter() {

        // Apply layout change, if any
        if (mLayoutId >= 0 || mLayout != null) {
        if (mLayoutId > 0 || mLayout != null) {
            // empty out parent container before adding to it
            getSceneRoot().removeAllViews();

            if (mLayoutId >= 0) {
            if (mLayoutId > 0) {
                LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
            } else {
                mSceneRoot.addView(mLayout);
@@ -242,4 +242,19 @@ public final class Scene {
        mExitAction = action;
    }


    /**
     * Returns whether this Scene was created by a layout resource file, determined
     * by the layoutId passed into
     * {@link #getSceneForLayout(android.view.ViewGroup, int, android.content.Context)}.
     * This is called by TransitionManager to determine whether it is safe for views from
     * this scene to be removed from their parents when the scene is exited, which is
     * used by {@link Fade} to fade these views out (the views must be removed from
     * their parent in order to add them to the overlay for fading purposes). If a
     * Scene is not based on a resource file, then the impact of removing views
     * arbitrarily is unknown and should be avoided.
     */
    boolean isCreatedFromLayoutResource() {
        return (mLayoutId > 0);
    }
}
 No newline at end of file
+12 −0
Original line number Diff line number Diff line
@@ -118,6 +118,14 @@ public abstract class Transition implements Cloneable {
    // Scene Root is set at createAnimator() time in the cloned Transition
    ViewGroup mSceneRoot = null;

    // Whether removing views from their parent is possible. This is only for views
    // in the start scene, which are no longer in the view hierarchy. This property
    // is determined by whether the previous Scene was created from a layout
    // resource, and thus the views from the exited scene are going away anyway
    // and can be removed as necessary to achieve a particular effect, such as
    // removing them from parents to add them to overlays.
    boolean mCanRemoveViews = false;

    // Track all animators in use in case the transition gets canceled and needs to
    // cancel running animators
    private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>();
@@ -1445,6 +1453,10 @@ public abstract class Transition implements Cloneable {
        return this;
    }

    void setCanRemoveViews(boolean canRemoveViews) {
        mCanRemoveViews = canRemoveViews;
    }

    @Override
    public String toString() {
        return toString("");
+5 −0
Original line number Diff line number Diff line
@@ -178,6 +178,11 @@ public class TransitionManager {
        Transition transitionClone = transition.clone();
        transitionClone.setSceneRoot(sceneRoot);

        Scene oldScene = Scene.getCurrentScene(sceneRoot);
        if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
            transitionClone.setCanRemoveViews(true);
        }

        sceneChangeSetup(sceneRoot, transitionClone);

        scene.enter();
Loading