14121f22713bbed467a977ec0d867ef53989ff374Dake Gu/*
24121f22713bbed467a977ec0d867ef53989ff374Dake Gu * Copyright (C) 2014 The Android Open Source Project
34121f22713bbed467a977ec0d867ef53989ff374Dake Gu *
44121f22713bbed467a977ec0d867ef53989ff374Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
54121f22713bbed467a977ec0d867ef53989ff374Dake Gu * in compliance with the License. You may obtain a copy of the License at
64121f22713bbed467a977ec0d867ef53989ff374Dake Gu *
74121f22713bbed467a977ec0d867ef53989ff374Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
84121f22713bbed467a977ec0d867ef53989ff374Dake Gu *
94121f22713bbed467a977ec0d867ef53989ff374Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
104121f22713bbed467a977ec0d867ef53989ff374Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
114121f22713bbed467a977ec0d867ef53989ff374Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
124121f22713bbed467a977ec0d867ef53989ff374Dake Gu * the License.
134121f22713bbed467a977ec0d867ef53989ff374Dake Gu */
144121f22713bbed467a977ec0d867ef53989ff374Dake Gupackage android.support.v17.leanback.widget;
154121f22713bbed467a977ec0d867ef53989ff374Dake Gu
16d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Guimport android.os.Handler;
174121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.support.v4.app.ActivityCompat;
189306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.support.v4.app.SharedElementCallback;
194121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.support.v4.view.ViewCompat;
20ceb7ab2ddd6e157cd4ade0f14a382c39428163c4Dake Guimport android.support.v17.leanback.R;
2195400e6d31a1ac09e48cb8944a79b7250484aa4cDake Guimport android.support.v17.leanback.transition.TransitionListener;
2295400e6d31a1ac09e48cb8944a79b7250484aa4cDake Guimport android.support.v17.leanback.transition.TransitionHelper;
234121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.support.v17.leanback.widget.DetailsOverviewRowPresenter.ViewHolder;
244121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.app.Activity;
25b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.content.Intent;
26b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.graphics.Matrix;
274121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.text.TextUtils;
28b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.util.Log;
294121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View;
3095400e6d31a1ac09e48cb8944a79b7250484aa4cDake Guimport android.view.ViewGroup;
314121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View.MeasureSpec;
32b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView;
33b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView.ScaleType;
344121f22713bbed467a977ec0d867ef53989ff374Dake Gu
354121f22713bbed467a977ec0d867ef53989ff374Dake Guimport java.util.List;
364121f22713bbed467a977ec0d867ef53989ff374Dake Gu
379306f07b1d66f4974a81f781d29739b30124fff0George Mountfinal class DetailsOverviewSharedElementHelper extends SharedElementCallback {
384121f22713bbed467a977ec0d867ef53989ff374Dake Gu
39b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private static final String TAG = "DetailsOverviewSharedElementHelper";
40b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private static final boolean DEBUG = false;
41b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
424121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private ViewHolder mViewHolder;
434121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private Activity mActivityToRunTransition;
4499881f0d15df96179f93eee2d624b338d327571cDake Gu    private boolean mStartedPostpone;
454121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private String mSharedElementName;
464121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private int mRightPanelWidth;
474121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private int mRightPanelHeight;
484121f22713bbed467a977ec0d867ef53989ff374Dake Gu
49b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private ScaleType mSavedScaleType;
50b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private Matrix mSavedMatrix;
51b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
52b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private boolean hasImageViewScaleChange(View snapshotView) {
53b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        return snapshotView instanceof ImageView;
54b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
55b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
56b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void saveImageViewScale() {
57b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (mSavedScaleType == null) {
58b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            // only save first time after initialize/restoreImageViewScale()
59b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            ImageView imageView = mViewHolder.mImageView;
60b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedScaleType = imageView.getScaleType();
61b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedMatrix = mSavedScaleType == ScaleType.MATRIX ? imageView.getMatrix() : null;
62b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (DEBUG) {
63b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                Log.d(TAG, "saveImageViewScale: "+mSavedScaleType);
64b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
65b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
66b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
67b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
68b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private static void updateImageViewAfterScaleTypeChange(ImageView imageView) {
69b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        // enforcing imageView to update its internal bounds/matrix immediately
70b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.measure(
71b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                MeasureSpec.makeMeasureSpec(imageView.getMeasuredWidth(), MeasureSpec.EXACTLY),
72b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                MeasureSpec.makeMeasureSpec(imageView.getMeasuredHeight(), MeasureSpec.EXACTLY));
73b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.layout(imageView.getLeft(), imageView.getTop(),
74b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                imageView.getRight(), imageView.getBottom());
75b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
76b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
77b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void changeImageViewScale(View snapshotView) {
78b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        ImageView snapshotImageView = (ImageView) snapshotView;
79b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        ImageView imageView = mViewHolder.mImageView;
80b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (DEBUG) {
81b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            Log.d(TAG, "changeImageViewScale to "+snapshotImageView.getScaleType());
82b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
83b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.setScaleType(snapshotImageView.getScaleType());
84b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (snapshotImageView.getScaleType() == ScaleType.MATRIX) {
85b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            imageView.setImageMatrix(snapshotImageView.getImageMatrix());
86b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
87b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        updateImageViewAfterScaleTypeChange(imageView);
88b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
89b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
90b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void restoreImageViewScale() {
91b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (mSavedScaleType != null) {
92b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (DEBUG) {
93b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                Log.d(TAG, "restoreImageViewScale to "+mSavedScaleType);
94b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
95b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            ImageView imageView = mViewHolder.mImageView;
96b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            imageView.setScaleType(mSavedScaleType);
97b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (mSavedScaleType == ScaleType.MATRIX) {
98b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                imageView.setImageMatrix(mSavedMatrix);
99b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
100b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            // only restore once unless another save happens
101b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedScaleType = null;
102b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            updateImageViewAfterScaleTypeChange(imageView);
103b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
104b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
105b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
1064121f22713bbed467a977ec0d867ef53989ff374Dake Gu    @Override
1079306f07b1d66f4974a81f781d29739b30124fff0George Mount    public void onSharedElementStart(List<String> sharedElementNames,
1084121f22713bbed467a977ec0d867ef53989ff374Dake Gu            List<View> sharedElements, List<View> sharedElementSnapshots) {
10999881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
11099881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onSharedElementStart " + mActivityToRunTransition);
11199881f0d15df96179f93eee2d624b338d327571cDake Gu        }
1124121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (sharedElements.size() < 1) {
1134121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1144121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1154121f22713bbed467a977ec0d867ef53989ff374Dake Gu        View overviewView = sharedElements.get(0);
116e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu        if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) {
1174121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1184121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
119b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        View snapshot = sharedElementSnapshots.get(0);
120b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (hasImageViewScaleChange(snapshot)) {
121b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            saveImageViewScale();
122b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            changeImageViewScale(snapshot);
123b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
1244121f22713bbed467a977ec0d867ef53989ff374Dake Gu        View imageView = mViewHolder.mImageView;
1254121f22713bbed467a977ec0d867ef53989ff374Dake Gu        final int width = overviewView.getWidth();
1264121f22713bbed467a977ec0d867ef53989ff374Dake Gu        final int height = overviewView.getHeight();
1274121f22713bbed467a977ec0d867ef53989ff374Dake Gu        imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
1284121f22713bbed467a977ec0d867ef53989ff374Dake Gu                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1294121f22713bbed467a977ec0d867ef53989ff374Dake Gu        imageView.layout(0, 0, width, height);
130b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        final View rightPanel = mViewHolder.mRightPanel;
1314121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (mRightPanelWidth != 0 && mRightPanelHeight != 0) {
1324121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.measure(MeasureSpec.makeMeasureSpec(mRightPanelWidth, MeasureSpec.EXACTLY),
1334121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    MeasureSpec.makeMeasureSpec(mRightPanelHeight, MeasureSpec.EXACTLY));
1344121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.layout(width, rightPanel.getTop(), width + mRightPanelWidth,
1354121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    rightPanel.getTop() + mRightPanelHeight);
1364121f22713bbed467a977ec0d867ef53989ff374Dake Gu        } else {
1374121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.offsetLeftAndRight(width - rightPanel.getLeft());
1384121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
13972a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mActionsRow.setVisibility(View.INVISIBLE);
14072a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mDetailsDescriptionFrame.setVisibility(View.INVISIBLE);
141b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu    }
142b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu
143b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu    @Override
1449306f07b1d66f4974a81f781d29739b30124fff0George Mount    public void onSharedElementEnd(List<String> sharedElementNames,
145b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            List<View> sharedElements, List<View> sharedElementSnapshots) {
14699881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
14799881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onSharedElementEnd " + mActivityToRunTransition);
14899881f0d15df96179f93eee2d624b338d327571cDake Gu        }
149b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        if (sharedElements.size() < 1) {
150b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            return;
151b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        }
152b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        View overviewView = sharedElements.get(0);
153e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu        if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) {
154b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            return;
155b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        }
156b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        restoreImageViewScale();
15795400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        // temporary let action row take focus so we defer button background animation
15895400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
15972a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mActionsRow.setVisibility(View.VISIBLE);
16095400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
16172a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mDetailsDescriptionFrame.setVisibility(View.VISIBLE);
1624121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
1634121f22713bbed467a977ec0d867ef53989ff374Dake Gu
164d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu    void setSharedElementEnterTransition(Activity activity, String sharedElementName,
165d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu            long timeoutMs) {
1664121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (activity == null && !TextUtils.isEmpty(sharedElementName) ||
1674121f22713bbed467a977ec0d867ef53989ff374Dake Gu                activity != null && TextUtils.isEmpty(sharedElementName)) {
1684121f22713bbed467a977ec0d867ef53989ff374Dake Gu            throw new IllegalArgumentException();
1694121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1704121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (activity == mActivityToRunTransition &&
1714121f22713bbed467a977ec0d867ef53989ff374Dake Gu                TextUtils.equals(sharedElementName, mSharedElementName)) {
1724121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1734121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1744121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (mActivityToRunTransition != null) {
1759306f07b1d66f4974a81f781d29739b30124fff0George Mount            ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, null);
1764121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1774121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mActivityToRunTransition = activity;
1784121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mSharedElementName = sharedElementName;
17999881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
18099881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "postponeEnterTransition " + mActivityToRunTransition);
18199881f0d15df96179f93eee2d624b338d327571cDake Gu        }
18299881f0d15df96179f93eee2d624b338d327571cDake Gu        ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, this);
18399881f0d15df96179f93eee2d624b338d327571cDake Gu        ActivityCompat.postponeEnterTransition(mActivityToRunTransition);
18499881f0d15df96179f93eee2d624b338d327571cDake Gu        if (timeoutMs > 0) {
18599881f0d15df96179f93eee2d624b338d327571cDake Gu            new Handler().postDelayed(new Runnable() {
18699881f0d15df96179f93eee2d624b338d327571cDake Gu                @Override
18799881f0d15df96179f93eee2d624b338d327571cDake Gu                public void run() {
18899881f0d15df96179f93eee2d624b338d327571cDake Gu                    if (mStartedPostpone) {
18999881f0d15df96179f93eee2d624b338d327571cDake Gu                        return;
19095400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu                    }
19199881f0d15df96179f93eee2d624b338d327571cDake Gu                    if (DEBUG) {
19299881f0d15df96179f93eee2d624b338d327571cDake Gu                        Log.d(TAG, "timeout " + mActivityToRunTransition);
19399881f0d15df96179f93eee2d624b338d327571cDake Gu                    }
19499881f0d15df96179f93eee2d624b338d327571cDake Gu                    startPostponedEnterTransition();
19599881f0d15df96179f93eee2d624b338d327571cDake Gu                }
19699881f0d15df96179f93eee2d624b338d327571cDake Gu            }, timeoutMs);
1974121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1984121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
1994121f22713bbed467a977ec0d867ef53989ff374Dake Gu
2004121f22713bbed467a977ec0d867ef53989ff374Dake Gu    void onBindToDrawable(ViewHolder vh) {
20199881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
20299881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onBindToDrawable, could start transition of " + mActivityToRunTransition);
20399881f0d15df96179f93eee2d624b338d327571cDake Gu        }
20499881f0d15df96179f93eee2d624b338d327571cDake Gu        if (mViewHolder != null) {
20599881f0d15df96179f93eee2d624b338d327571cDake Gu            if (DEBUG) {
20699881f0d15df96179f93eee2d624b338d327571cDake Gu                Log.d(TAG, "rebind? clear transitionName on current viewHolder "
20799881f0d15df96179f93eee2d624b338d327571cDake Gu                        + mViewHolder.mOverviewFrame);
20899881f0d15df96179f93eee2d624b338d327571cDake Gu            }
20999881f0d15df96179f93eee2d624b338d327571cDake Gu            ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, null);
21099881f0d15df96179f93eee2d624b338d327571cDake Gu        }
2114121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // After we got a image drawable,  we can determine size of right panel.
2124121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // We want right panel to have fixed size so that the right panel don't change size
2134121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // when the overview is layout as a small bounds in transition.
2144121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mViewHolder = vh;
2154121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
2164121f22713bbed467a977ec0d867ef53989ff374Dake Gu            @Override
2174121f22713bbed467a977ec0d867ef53989ff374Dake Gu            public void onLayoutChange(View v, int left, int top, int right, int bottom,
2184121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
2194121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mViewHolder.mRightPanel.removeOnLayoutChangeListener(this);
2204121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mRightPanelWidth = mViewHolder.mRightPanel.getWidth();
2214121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mRightPanelHeight = mViewHolder.mRightPanel.getHeight();
22299881f0d15df96179f93eee2d624b338d327571cDake Gu                if (DEBUG) {
22399881f0d15df96179f93eee2d624b338d327571cDake Gu                    Log.d(TAG, "onLayoutChange records size of right panel as "
22499881f0d15df96179f93eee2d624b338d327571cDake Gu                            + mRightPanelWidth + ", "+ mRightPanelHeight);
22599881f0d15df96179f93eee2d624b338d327571cDake Gu                }
2264121f22713bbed467a977ec0d867ef53989ff374Dake Gu            }
2274121f22713bbed467a977ec0d867ef53989ff374Dake Gu        });
22899881f0d15df96179f93eee2d624b338d327571cDake Gu        mViewHolder.mRightPanel.postOnAnimation(new Runnable() {
22999881f0d15df96179f93eee2d624b338d327571cDake Gu            @Override
23099881f0d15df96179f93eee2d624b338d327571cDake Gu            public void run() {
23199881f0d15df96179f93eee2d624b338d327571cDake Gu                if (DEBUG) {
23299881f0d15df96179f93eee2d624b338d327571cDake Gu                    Log.d(TAG, "setTransitionName "+mViewHolder.mOverviewFrame);
23399881f0d15df96179f93eee2d624b338d327571cDake Gu                }
23499881f0d15df96179f93eee2d624b338d327571cDake Gu                ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, mSharedElementName);
23599881f0d15df96179f93eee2d624b338d327571cDake Gu                final TransitionHelper transitionHelper = TransitionHelper.getInstance();
23699881f0d15df96179f93eee2d624b338d327571cDake Gu                Object transition = transitionHelper.getSharedElementEnterTransition(
23799881f0d15df96179f93eee2d624b338d327571cDake Gu                        mActivityToRunTransition.getWindow());
23899881f0d15df96179f93eee2d624b338d327571cDake Gu                if (transition != null) {
23999881f0d15df96179f93eee2d624b338d327571cDake Gu                    transitionHelper.setTransitionListener(transition, new TransitionListener() {
24099881f0d15df96179f93eee2d624b338d327571cDake Gu                        @Override
24199881f0d15df96179f93eee2d624b338d327571cDake Gu                        public void onTransitionEnd(Object transition) {
24299881f0d15df96179f93eee2d624b338d327571cDake Gu                            if (DEBUG) {
24399881f0d15df96179f93eee2d624b338d327571cDake Gu                                Log.d(TAG, "onTransitionEnd " + mActivityToRunTransition);
244d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu                            }
24599881f0d15df96179f93eee2d624b338d327571cDake Gu                            // after transition if the action row still focused, transfer
24699881f0d15df96179f93eee2d624b338d327571cDake Gu                            // focus to its children
24799881f0d15df96179f93eee2d624b338d327571cDake Gu                            if (mViewHolder.mActionsRow.isFocused()) {
24899881f0d15df96179f93eee2d624b338d327571cDake Gu                                mViewHolder.mActionsRow.requestFocus();
24999881f0d15df96179f93eee2d624b338d327571cDake Gu                            }
25099881f0d15df96179f93eee2d624b338d327571cDake Gu                            transitionHelper.setTransitionListener(transition, null);
25199881f0d15df96179f93eee2d624b338d327571cDake Gu                        }
25299881f0d15df96179f93eee2d624b338d327571cDake Gu                    });
2534121f22713bbed467a977ec0d867ef53989ff374Dake Gu                }
25499881f0d15df96179f93eee2d624b338d327571cDake Gu                startPostponedEnterTransition();
25599881f0d15df96179f93eee2d624b338d327571cDake Gu            }
25699881f0d15df96179f93eee2d624b338d327571cDake Gu        });
25799881f0d15df96179f93eee2d624b338d327571cDake Gu    }
25899881f0d15df96179f93eee2d624b338d327571cDake Gu
25999881f0d15df96179f93eee2d624b338d327571cDake Gu    private void startPostponedEnterTransition() {
26099881f0d15df96179f93eee2d624b338d327571cDake Gu        if (!mStartedPostpone) {
26199881f0d15df96179f93eee2d624b338d327571cDake Gu            if (DEBUG) {
26299881f0d15df96179f93eee2d624b338d327571cDake Gu                Log.d(TAG, "startPostponedEnterTransition " + mActivityToRunTransition);
26399881f0d15df96179f93eee2d624b338d327571cDake Gu            }
26499881f0d15df96179f93eee2d624b338d327571cDake Gu            ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition);
26599881f0d15df96179f93eee2d624b338d327571cDake Gu            mStartedPostpone = true;
2664121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
2674121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
2684121f22713bbed467a977ec0d867ef53989ff374Dake Gu}
269