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
163103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.app.Activity;
173103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.graphics.Matrix;
18d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Guimport android.os.Handler;
193103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.support.v17.leanback.transition.TransitionHelper;
203103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.support.v17.leanback.transition.TransitionListener;
213103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.support.v17.leanback.widget.DetailsOverviewRowPresenter.ViewHolder;
224121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.support.v4.app.ActivityCompat;
239306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.support.v4.app.SharedElementCallback;
244121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.support.v4.view.ViewCompat;
254121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.text.TextUtils;
26b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.util.Log;
274121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View;
284121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View.MeasureSpec;
293103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.view.ViewGroup;
30b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView;
31b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView.ScaleType;
324121f22713bbed467a977ec0d867ef53989ff374Dake Gu
332056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Guimport java.lang.ref.WeakReference;
344121f22713bbed467a977ec0d867ef53989ff374Dake Guimport java.util.List;
354121f22713bbed467a977ec0d867ef53989ff374Dake Gu
369306f07b1d66f4974a81f781d29739b30124fff0George Mountfinal class DetailsOverviewSharedElementHelper extends SharedElementCallback {
374121f22713bbed467a977ec0d867ef53989ff374Dake Gu
382056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu    static final String TAG = "DetailsTransitionHelper";
3999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static final boolean DEBUG = false;
40b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
412056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu    static class TransitionTimeOutRunnable implements Runnable {
422056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        WeakReference<DetailsOverviewSharedElementHelper> mHelperRef;
432056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu
442056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        TransitionTimeOutRunnable(DetailsOverviewSharedElementHelper helper) {
452056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            mHelperRef = new WeakReference<DetailsOverviewSharedElementHelper>(helper);
462056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        }
472056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu
482056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        @Override
492056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        public void run() {
502056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            DetailsOverviewSharedElementHelper helper = mHelperRef.get();
512056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            if (helper == null) {
522056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu                return;
532056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            }
542056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            if (DEBUG) {
552056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu                Log.d(TAG, "timeout " + helper.mActivityToRunTransition);
562056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            }
572056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            helper.startPostponedEnterTransition();
582056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu        }
592056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu    }
602056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu
6199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    ViewHolder mViewHolder;
6299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    Activity mActivityToRunTransition;
6399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    boolean mStartedPostpone;
6499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    String mSharedElementName;
6599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mRightPanelWidth;
6699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mRightPanelHeight;
674121f22713bbed467a977ec0d867ef53989ff374Dake Gu
68b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private ScaleType mSavedScaleType;
69b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private Matrix mSavedMatrix;
70b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
71b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private boolean hasImageViewScaleChange(View snapshotView) {
72b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        return snapshotView instanceof ImageView;
73b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
74b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
75b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void saveImageViewScale() {
76b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (mSavedScaleType == null) {
77b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            // only save first time after initialize/restoreImageViewScale()
78b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            ImageView imageView = mViewHolder.mImageView;
79b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedScaleType = imageView.getScaleType();
80b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedMatrix = mSavedScaleType == ScaleType.MATRIX ? imageView.getMatrix() : null;
81b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (DEBUG) {
82b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                Log.d(TAG, "saveImageViewScale: "+mSavedScaleType);
83b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
84b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
85b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
86b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
87b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private static void updateImageViewAfterScaleTypeChange(ImageView imageView) {
88b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        // enforcing imageView to update its internal bounds/matrix immediately
89b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.measure(
90b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                MeasureSpec.makeMeasureSpec(imageView.getMeasuredWidth(), MeasureSpec.EXACTLY),
91b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                MeasureSpec.makeMeasureSpec(imageView.getMeasuredHeight(), MeasureSpec.EXACTLY));
92b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.layout(imageView.getLeft(), imageView.getTop(),
93b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                imageView.getRight(), imageView.getBottom());
94b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
95b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
96b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void changeImageViewScale(View snapshotView) {
97b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        ImageView snapshotImageView = (ImageView) snapshotView;
98b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        ImageView imageView = mViewHolder.mImageView;
99b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (DEBUG) {
100b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            Log.d(TAG, "changeImageViewScale to "+snapshotImageView.getScaleType());
101b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
102b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        imageView.setScaleType(snapshotImageView.getScaleType());
103b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (snapshotImageView.getScaleType() == ScaleType.MATRIX) {
104b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            imageView.setImageMatrix(snapshotImageView.getImageMatrix());
105b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
106b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        updateImageViewAfterScaleTypeChange(imageView);
107b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
108b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
109b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    private void restoreImageViewScale() {
110b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (mSavedScaleType != null) {
111b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (DEBUG) {
112b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                Log.d(TAG, "restoreImageViewScale to "+mSavedScaleType);
113b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
114b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            ImageView imageView = mViewHolder.mImageView;
115b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            imageView.setScaleType(mSavedScaleType);
116b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            if (mSavedScaleType == ScaleType.MATRIX) {
117b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu                imageView.setImageMatrix(mSavedMatrix);
118b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            }
119b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            // only restore once unless another save happens
120b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            mSavedScaleType = null;
121b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            updateImageViewAfterScaleTypeChange(imageView);
122b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
123b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu    }
124b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu
1254121f22713bbed467a977ec0d867ef53989ff374Dake Gu    @Override
1269306f07b1d66f4974a81f781d29739b30124fff0George Mount    public void onSharedElementStart(List<String> sharedElementNames,
1274121f22713bbed467a977ec0d867ef53989ff374Dake Gu            List<View> sharedElements, List<View> sharedElementSnapshots) {
12899881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
12999881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onSharedElementStart " + mActivityToRunTransition);
13099881f0d15df96179f93eee2d624b338d327571cDake Gu        }
1314121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (sharedElements.size() < 1) {
1324121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1334121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1344121f22713bbed467a977ec0d867ef53989ff374Dake Gu        View overviewView = sharedElements.get(0);
135e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu        if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) {
1364121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1374121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
138b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        View snapshot = sharedElementSnapshots.get(0);
139b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        if (hasImageViewScaleChange(snapshot)) {
140b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            saveImageViewScale();
141b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu            changeImageViewScale(snapshot);
142b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        }
1434121f22713bbed467a977ec0d867ef53989ff374Dake Gu        View imageView = mViewHolder.mImageView;
1444121f22713bbed467a977ec0d867ef53989ff374Dake Gu        final int width = overviewView.getWidth();
1454121f22713bbed467a977ec0d867ef53989ff374Dake Gu        final int height = overviewView.getHeight();
1464121f22713bbed467a977ec0d867ef53989ff374Dake Gu        imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
1474121f22713bbed467a977ec0d867ef53989ff374Dake Gu                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1484121f22713bbed467a977ec0d867ef53989ff374Dake Gu        imageView.layout(0, 0, width, height);
149b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        final View rightPanel = mViewHolder.mRightPanel;
1504121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (mRightPanelWidth != 0 && mRightPanelHeight != 0) {
1514121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.measure(MeasureSpec.makeMeasureSpec(mRightPanelWidth, MeasureSpec.EXACTLY),
1524121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    MeasureSpec.makeMeasureSpec(mRightPanelHeight, MeasureSpec.EXACTLY));
1534121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.layout(width, rightPanel.getTop(), width + mRightPanelWidth,
1544121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    rightPanel.getTop() + mRightPanelHeight);
1554121f22713bbed467a977ec0d867ef53989ff374Dake Gu        } else {
1564121f22713bbed467a977ec0d867ef53989ff374Dake Gu            rightPanel.offsetLeftAndRight(width - rightPanel.getLeft());
1574121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
15872a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mActionsRow.setVisibility(View.INVISIBLE);
15972a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mDetailsDescriptionFrame.setVisibility(View.INVISIBLE);
160b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu    }
161b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu
162b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu    @Override
1639306f07b1d66f4974a81f781d29739b30124fff0George Mount    public void onSharedElementEnd(List<String> sharedElementNames,
164b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            List<View> sharedElements, List<View> sharedElementSnapshots) {
16599881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
16699881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onSharedElementEnd " + mActivityToRunTransition);
16799881f0d15df96179f93eee2d624b338d327571cDake Gu        }
168b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        if (sharedElements.size() < 1) {
169b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            return;
170b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        }
171b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        View overviewView = sharedElements.get(0);
172e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu        if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) {
173b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu            return;
174b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu        }
175b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu        restoreImageViewScale();
17695400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        // temporary let action row take focus so we defer button background animation
17795400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
17872a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mActionsRow.setVisibility(View.VISIBLE);
17995400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu        mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
18072a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu        mViewHolder.mDetailsDescriptionFrame.setVisibility(View.VISIBLE);
1814121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
1824121f22713bbed467a977ec0d867ef53989ff374Dake Gu
183d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu    void setSharedElementEnterTransition(Activity activity, String sharedElementName,
184d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu            long timeoutMs) {
185694edde99dc3782374977dab6d9aa34a16c13337Dake Gu        if ((activity == null && !TextUtils.isEmpty(sharedElementName))
186694edde99dc3782374977dab6d9aa34a16c13337Dake Gu                || (activity != null && TextUtils.isEmpty(sharedElementName))) {
1874121f22713bbed467a977ec0d867ef53989ff374Dake Gu            throw new IllegalArgumentException();
1884121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1893103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        if (activity == mActivityToRunTransition
1903103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                && TextUtils.equals(sharedElementName, mSharedElementName)) {
1914121f22713bbed467a977ec0d867ef53989ff374Dake Gu            return;
1924121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1934121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (mActivityToRunTransition != null) {
1949306f07b1d66f4974a81f781d29739b30124fff0George Mount            ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, null);
1954121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
1964121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mActivityToRunTransition = activity;
1974121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mSharedElementName = sharedElementName;
19899881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
19999881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "postponeEnterTransition " + mActivityToRunTransition);
20099881f0d15df96179f93eee2d624b338d327571cDake Gu        }
20199881f0d15df96179f93eee2d624b338d327571cDake Gu        ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, this);
20299881f0d15df96179f93eee2d624b338d327571cDake Gu        ActivityCompat.postponeEnterTransition(mActivityToRunTransition);
20399881f0d15df96179f93eee2d624b338d327571cDake Gu        if (timeoutMs > 0) {
2042056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu            new Handler().postDelayed(new TransitionTimeOutRunnable(this), timeoutMs);
2054121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
2064121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
2074121f22713bbed467a977ec0d867ef53989ff374Dake Gu
2084121f22713bbed467a977ec0d867ef53989ff374Dake Gu    void onBindToDrawable(ViewHolder vh) {
20999881f0d15df96179f93eee2d624b338d327571cDake Gu        if (DEBUG) {
21099881f0d15df96179f93eee2d624b338d327571cDake Gu            Log.d(TAG, "onBindToDrawable, could start transition of " + mActivityToRunTransition);
21199881f0d15df96179f93eee2d624b338d327571cDake Gu        }
21299881f0d15df96179f93eee2d624b338d327571cDake Gu        if (mViewHolder != null) {
21399881f0d15df96179f93eee2d624b338d327571cDake Gu            if (DEBUG) {
21499881f0d15df96179f93eee2d624b338d327571cDake Gu                Log.d(TAG, "rebind? clear transitionName on current viewHolder "
21599881f0d15df96179f93eee2d624b338d327571cDake Gu                        + mViewHolder.mOverviewFrame);
21699881f0d15df96179f93eee2d624b338d327571cDake Gu            }
21799881f0d15df96179f93eee2d624b338d327571cDake Gu            ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, null);
21899881f0d15df96179f93eee2d624b338d327571cDake Gu        }
2194121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // After we got a image drawable,  we can determine size of right panel.
2204121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // We want right panel to have fixed size so that the right panel don't change size
2214121f22713bbed467a977ec0d867ef53989ff374Dake Gu        // when the overview is layout as a small bounds in transition.
2224121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mViewHolder = vh;
2234121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
2244121f22713bbed467a977ec0d867ef53989ff374Dake Gu            @Override
2254121f22713bbed467a977ec0d867ef53989ff374Dake Gu            public void onLayoutChange(View v, int left, int top, int right, int bottom,
2264121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
2274121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mViewHolder.mRightPanel.removeOnLayoutChangeListener(this);
2284121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mRightPanelWidth = mViewHolder.mRightPanel.getWidth();
2294121f22713bbed467a977ec0d867ef53989ff374Dake Gu                mRightPanelHeight = mViewHolder.mRightPanel.getHeight();
23099881f0d15df96179f93eee2d624b338d327571cDake Gu                if (DEBUG) {
23199881f0d15df96179f93eee2d624b338d327571cDake Gu                    Log.d(TAG, "onLayoutChange records size of right panel as "
23299881f0d15df96179f93eee2d624b338d327571cDake Gu                            + mRightPanelWidth + ", "+ mRightPanelHeight);
23399881f0d15df96179f93eee2d624b338d327571cDake Gu                }
2344121f22713bbed467a977ec0d867ef53989ff374Dake Gu            }
2354121f22713bbed467a977ec0d867ef53989ff374Dake Gu        });
23699881f0d15df96179f93eee2d624b338d327571cDake Gu        mViewHolder.mRightPanel.postOnAnimation(new Runnable() {
23799881f0d15df96179f93eee2d624b338d327571cDake Gu            @Override
23899881f0d15df96179f93eee2d624b338d327571cDake Gu            public void run() {
23999881f0d15df96179f93eee2d624b338d327571cDake Gu                if (DEBUG) {
24099881f0d15df96179f93eee2d624b338d327571cDake Gu                    Log.d(TAG, "setTransitionName "+mViewHolder.mOverviewFrame);
24199881f0d15df96179f93eee2d624b338d327571cDake Gu                }
24299881f0d15df96179f93eee2d624b338d327571cDake Gu                ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, mSharedElementName);
2438403619efebe94666c0615c3fc85080a303acf80Dake Gu                Object transition = TransitionHelper.getSharedElementEnterTransition(
24499881f0d15df96179f93eee2d624b338d327571cDake Gu                        mActivityToRunTransition.getWindow());
24599881f0d15df96179f93eee2d624b338d327571cDake Gu                if (transition != null) {
2468403619efebe94666c0615c3fc85080a303acf80Dake Gu                    TransitionHelper.addTransitionListener(transition, new TransitionListener() {
24799881f0d15df96179f93eee2d624b338d327571cDake Gu                        @Override
24899881f0d15df96179f93eee2d624b338d327571cDake Gu                        public void onTransitionEnd(Object transition) {
24999881f0d15df96179f93eee2d624b338d327571cDake Gu                            if (DEBUG) {
25099881f0d15df96179f93eee2d624b338d327571cDake Gu                                Log.d(TAG, "onTransitionEnd " + mActivityToRunTransition);
251d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu                            }
25299881f0d15df96179f93eee2d624b338d327571cDake Gu                            // after transition if the action row still focused, transfer
25399881f0d15df96179f93eee2d624b338d327571cDake Gu                            // focus to its children
25499881f0d15df96179f93eee2d624b338d327571cDake Gu                            if (mViewHolder.mActionsRow.isFocused()) {
25599881f0d15df96179f93eee2d624b338d327571cDake Gu                                mViewHolder.mActionsRow.requestFocus();
25699881f0d15df96179f93eee2d624b338d327571cDake Gu                            }
2578403619efebe94666c0615c3fc85080a303acf80Dake Gu                            TransitionHelper.removeTransitionListener(transition, this);
25899881f0d15df96179f93eee2d624b338d327571cDake Gu                        }
25999881f0d15df96179f93eee2d624b338d327571cDake Gu                    });
2604121f22713bbed467a977ec0d867ef53989ff374Dake Gu                }
26199881f0d15df96179f93eee2d624b338d327571cDake Gu                startPostponedEnterTransition();
26299881f0d15df96179f93eee2d624b338d327571cDake Gu            }
26399881f0d15df96179f93eee2d624b338d327571cDake Gu        });
26499881f0d15df96179f93eee2d624b338d327571cDake Gu    }
26599881f0d15df96179f93eee2d624b338d327571cDake Gu
26699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void startPostponedEnterTransition() {
26799881f0d15df96179f93eee2d624b338d327571cDake Gu        if (!mStartedPostpone) {
26899881f0d15df96179f93eee2d624b338d327571cDake Gu            if (DEBUG) {
26999881f0d15df96179f93eee2d624b338d327571cDake Gu                Log.d(TAG, "startPostponedEnterTransition " + mActivityToRunTransition);
27099881f0d15df96179f93eee2d624b338d327571cDake Gu            }
27199881f0d15df96179f93eee2d624b338d327571cDake Gu            ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition);
27299881f0d15df96179f93eee2d624b338d327571cDake Gu            mStartedPostpone = true;
2734121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
2744121f22713bbed467a977ec0d867ef53989ff374Dake Gu    }
2754121f22713bbed467a977ec0d867ef53989ff374Dake Gu}
276