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

Commit b963e139 authored by George Mount's avatar George Mount Committed by Android (Google) Code Review
Browse files

Merge "Better coordination of transition destination."

parents 129e7ac8 67d92434
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -206,6 +206,9 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
    protected ResultReceiver mResultReceiver;
    final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback();
    final protected boolean mIsReturning;
    private Runnable mPendingTransition;
    private boolean mIsStartingTransition;


    public ActivityTransitionCoordinator(Window window,
            ArrayList<String> allSharedElementNames,
@@ -523,7 +526,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
     * @param transitionArgs Bundle to store shared element placement information.
     * @param tempBounds     A temporary Rect for capturing the current location of views.
     */
    private static void captureSharedElementState(View view, String name, Bundle transitionArgs,
    protected static void captureSharedElementState(View view, String name, Bundle transitionArgs,
            Rect tempBounds) {
        Bundle sharedElementBundle = new Bundle();
        tempBounds.set(0, 0, view.getWidth(), view.getHeight());
@@ -559,6 +562,28 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
        transitionArgs.putBundle(name, sharedElementBundle);
    }


    protected void startTransition(Runnable runnable) {
        if (mIsStartingTransition) {
            mPendingTransition = runnable;
        } else {
            mIsStartingTransition = true;
            runnable.run();
        }
    }

    protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
        @Override
        public void onTransitionStart(Transition transition) {
            mIsStartingTransition = false;
            Runnable pending = mPendingTransition;
            mPendingTransition = null;
            if (pending != null) {
                startTransition(pending);
            }
        }
    }

    private static int scaleTypeToInt(ImageView.ScaleType scaleType) {
        for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) {
            if (scaleType == SCALE_TYPE_VALUES[i]) {
+12 −1
Original line number Diff line number Diff line
@@ -106,7 +106,16 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {

    private void sendSharedElementDestination() {
        ViewGroup decor = getDecor();
        if (!decor.isLayoutRequested()) {
        boolean allReady = !decor.isLayoutRequested();
        if (allReady) {
            for (int i = 0; i < mSharedElements.size(); i++) {
                if (mSharedElements.get(i).isLayoutRequested()) {
                    allReady = false;
                    break;
                }
            }
        }
        if (allReady) {
            Bundle state = captureSharedElementState();
            mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
        } else {
@@ -115,6 +124,8 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
                        @Override
                        public boolean onPreDraw() {
                            getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
                            Bundle state = captureSharedElementState();
                            mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
                            return true;
                        }
                    });
+99 −36
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -27,6 +28,7 @@ import android.os.Message;
import android.transition.Transition;
import android.transition.TransitionManager;
import android.view.View;
import android.view.ViewGroupOverlay;
import android.view.ViewTreeObserver;

import java.util.ArrayList;
@@ -60,10 +62,10 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {

    private boolean mIsHidden;

    private boolean mExitTransitionStarted;

    private Bundle mExitSharedElementBundle;

    private ArrayList<View> mSharedElementSnapshots;

    public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
            ArrayList<String> accepted, ArrayList<String> mapped, boolean isReturning) {
        super(activity.getWindow(), names, accepted, mapped, getListener(activity, isReturning),
@@ -106,30 +108,81 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
                break;
            case MSG_SHARED_ELEMENT_DESTINATION:
                mExitSharedElementBundle = resultData;
                if (mExitTransitionStarted) {
                sharedElementExitBack();
                break;
        }
    }

    private void sharedElementExitBack() {
        if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) {
            startTransition(new Runnable() {
                public void run() {
                    startSharedElementExit();
                }
                break;
            });
        }
    }

    private void startSharedElementExit() {
        if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) {
        Transition transition = getSharedElementExitTransition();
            TransitionManager.beginDelayedTransition(getDecor(), transition);
            ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
        final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
                mSharedElementNames);
        mSharedElementSnapshots = createSnapshots(mExitSharedElementBundle, mSharedElementNames);
        transition.addListener(new Transition.TransitionListenerAdapter() {
            @Override
            public void onTransitionEnd(Transition transition) {
                setViewVisibility(mSharedElements, View.INVISIBLE);
                ViewGroupOverlay overlay = getDecor().getOverlay();
                for (int i = 0; i < mSharedElementSnapshots.size(); i++) {
                    overlay.add(mSharedElementSnapshots.get(i));
                }
            }
        });
        getDecor().getViewTreeObserver()
                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                    @Override
                    public boolean onPreDraw() {
                        getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
                        return true;
                    }
                });
        TransitionManager.beginDelayedTransition(getDecor(), transition);
        getDecor().invalidate();
    }

    private static ArrayList<View> copySnapshots(ArrayList<View> snapshots) {
        ArrayList<View> copy = new ArrayList<View>(snapshots.size());
        for (int i = 0; i < snapshots.size(); i++) {
            View view = snapshots.get(i);
            View viewCopy = new View(view.getContext());
            viewCopy.setBackground(view.getBackground());
            copy.add(viewCopy);
        }
        return copy;
    }

    private void hideSharedElements() {
        if (!mIsHidden) {
            setViewVisibility(mSharedElements, View.INVISIBLE);
        }
        if (mSharedElementSnapshots != null) {
            ViewGroupOverlay overlay = getDecor().getOverlay();
            for (int i = 0; i < mSharedElementSnapshots.size(); i++) {
                overlay.remove(mSharedElementSnapshots.get(i));
            }
            mSharedElementSnapshots = null;
        }
        finishIfNecessary();
    }

    public void startExit() {
        startTransition(new Runnable() {
            @Override
            public void run() {
                beginTransitions();
            }
        });
        setViewVisibility(mTransitioningViews, View.INVISIBLE);
    }

@@ -159,29 +212,25 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
                }
            }
        }, options);
        startTransition(new Runnable() {
            @Override
            public void run() {
                startExitTransition();
            }
        });
    }

    private void startExitTransition() {
        Transition sharedElementTransition = mSharedElements.isEmpty()
                ? null : getSharedElementTransition();
        if (sharedElementTransition == null) {
            sharedElementTransitionComplete();
        }
        Transition transition = mergeTransitions(sharedElementTransition, getExitTransition());
        if (transition == null) {
            mExitTransitionStarted = true;
        } else {
        Transition transition = mergeTransitions(sharedElementTransition,
                getExitTransition());
        if (transition != null) {
            TransitionManager.beginDelayedTransition(getDecor(), transition);
            setViewVisibility(mTransitioningViews, View.INVISIBLE);
            getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
                    mExitTransitionStarted = true;
                    if (mExitSharedElementBundle != null) {
                        startSharedElementExit();
                    }
                    notifyComplete();
                    return true;
                }
            });
        }
    }

@@ -212,7 +261,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
        if (viewsTransition == null) {
            exitTransitionComplete();
        } else {
            viewsTransition.addListener(new Transition.TransitionListenerAdapter() {
            viewsTransition.addListener(new ContinueTransitionListener() {
                @Override
                public void onTransitionEnd(Transition transition) {
                    exitTransitionComplete();
@@ -238,7 +287,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
        if (sharedElementTransition == null) {
            sharedElementTransitionComplete();
        } else {
            sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() {
            sharedElementTransition.addListener(new ContinueTransitionListener() {
                @Override
                public void onTransitionEnd(Transition transition) {
                    sharedElementTransitionComplete();
@@ -257,7 +306,6 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
        Transition viewsTransition = getExitTransition();

        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
        mExitTransitionStarted = true;
        if (transition != null) {
            TransitionManager.beginDelayedTransition(getDecor(), transition);
        }
@@ -269,15 +317,31 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
    }

    protected boolean isReadyToNotify() {
        return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady
                && mExitTransitionStarted;
        return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
    }

    private void sharedElementTransitionComplete() {
        mSharedElementBundle = captureSharedElementState();
        mSharedElementBundle = mExitSharedElementBundle == null
                ? captureSharedElementState() : captureExitSharedElementsState();
        notifyComplete();
    }

    private Bundle captureExitSharedElementsState() {
        Bundle bundle = new Bundle();
        Rect bounds = new Rect();
        for (int i = 0; i < mSharedElementNames.size(); i++) {
            String name = mSharedElementNames.get(i);
            Bundle sharedElementState = mExitSharedElementBundle.getBundle(name);
            if (sharedElementState != null) {
                bundle.putBundle(name, sharedElementState);
            } else {
                View view = mSharedElements.get(i);
                captureSharedElementState(view, name, bundle, bounds);
            }
        }
        return bundle;
    }

    protected void notifyComplete() {
        if (isReadyToNotify()) {
            if (!mSharedElementNotified) {
@@ -294,8 +358,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
    }

    private void finishIfNecessary() {
        if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty()
                || mSharedElements.get(0).getVisibility() == View.INVISIBLE)) {
        if (mIsReturning && mExitNotified && mActivity != null && mSharedElementSnapshots == null) {
            mActivity.finish();
            mActivity.overridePendingTransition(0, 0);
            mActivity = null;