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 */ 14ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.widget; 154121f22713bbed467a977ec0d867ef53989ff374Dake Gu 163103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.app.Activity; 173103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.graphics.Matrix; 18d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Guimport android.os.Handler; 194121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.text.TextUtils; 20b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.util.Log; 214121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View; 224121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.view.View.MeasureSpec; 233103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.view.ViewGroup; 24b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView; 25b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView.ScaleType; 264121f22713bbed467a977ec0d867ef53989ff374Dake Gu 278619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.core.app.ActivityCompat; 288619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.core.app.SharedElementCallback; 298619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.core.view.ViewCompat; 308619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.transition.TransitionHelper; 318619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.transition.TransitionListener; 328619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.widget.DetailsOverviewRowPresenter.ViewHolder; 338619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas 342056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Guimport java.lang.ref.WeakReference; 354121f22713bbed467a977ec0d867ef53989ff374Dake Guimport java.util.List; 364121f22713bbed467a977ec0d867ef53989ff374Dake Gu 379306f07b1d66f4974a81f781d29739b30124fff0George Mountfinal class DetailsOverviewSharedElementHelper extends SharedElementCallback { 384121f22713bbed467a977ec0d867ef53989ff374Dake Gu 392056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu static final String TAG = "DetailsTransitionHelper"; 4099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas static final boolean DEBUG = false; 41b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 422056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu static class TransitionTimeOutRunnable implements Runnable { 432056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu WeakReference<DetailsOverviewSharedElementHelper> mHelperRef; 442056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu 452056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu TransitionTimeOutRunnable(DetailsOverviewSharedElementHelper helper) { 462056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu mHelperRef = new WeakReference<DetailsOverviewSharedElementHelper>(helper); 472056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu } 482056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu 492056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu @Override 502056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu public void run() { 512056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu DetailsOverviewSharedElementHelper helper = mHelperRef.get(); 522056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu if (helper == null) { 532056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu return; 542056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu } 552056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu if (DEBUG) { 562056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu Log.d(TAG, "timeout " + helper.mActivityToRunTransition); 572056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu } 582056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu helper.startPostponedEnterTransition(); 592056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu } 602056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu } 612056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu 6299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas ViewHolder mViewHolder; 6399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Activity mActivityToRunTransition; 6499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas boolean mStartedPostpone; 6599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas String mSharedElementName; 6699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas int mRightPanelWidth; 6799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas int mRightPanelHeight; 684121f22713bbed467a977ec0d867ef53989ff374Dake Gu 69b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private ScaleType mSavedScaleType; 70b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private Matrix mSavedMatrix; 71b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 72b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private boolean hasImageViewScaleChange(View snapshotView) { 73b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return snapshotView instanceof ImageView; 74b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 75b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 76b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private void saveImageViewScale() { 77b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (mSavedScaleType == null) { 78b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu // only save first time after initialize/restoreImageViewScale() 79b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = mViewHolder.mImageView; 80b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu mSavedScaleType = imageView.getScaleType(); 81b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu mSavedMatrix = mSavedScaleType == ScaleType.MATRIX ? imageView.getMatrix() : null; 82b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (DEBUG) { 83b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Log.d(TAG, "saveImageViewScale: "+mSavedScaleType); 84b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 85b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 86b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 87b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 88b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static void updateImageViewAfterScaleTypeChange(ImageView imageView) { 89b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu // enforcing imageView to update its internal bounds/matrix immediately 90b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.measure( 91b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu MeasureSpec.makeMeasureSpec(imageView.getMeasuredWidth(), MeasureSpec.EXACTLY), 92b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu MeasureSpec.makeMeasureSpec(imageView.getMeasuredHeight(), MeasureSpec.EXACTLY)); 93b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.layout(imageView.getLeft(), imageView.getTop(), 94b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.getRight(), imageView.getBottom()); 95b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 96b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 97b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private void changeImageViewScale(View snapshotView) { 98b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView snapshotImageView = (ImageView) snapshotView; 99b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = mViewHolder.mImageView; 100b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (DEBUG) { 101b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Log.d(TAG, "changeImageViewScale to "+snapshotImageView.getScaleType()); 102b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 103b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setScaleType(snapshotImageView.getScaleType()); 104b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (snapshotImageView.getScaleType() == ScaleType.MATRIX) { 105b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageMatrix(snapshotImageView.getImageMatrix()); 106b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 107b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu updateImageViewAfterScaleTypeChange(imageView); 108b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 109b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 110b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private void restoreImageViewScale() { 111b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (mSavedScaleType != null) { 112b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (DEBUG) { 113b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Log.d(TAG, "restoreImageViewScale to "+mSavedScaleType); 114b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 115b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = mViewHolder.mImageView; 116b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setScaleType(mSavedScaleType); 117b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (mSavedScaleType == ScaleType.MATRIX) { 118b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageMatrix(mSavedMatrix); 119b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 120b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu // only restore once unless another save happens 121b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu mSavedScaleType = null; 122b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu updateImageViewAfterScaleTypeChange(imageView); 123b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 124b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 125b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 1264121f22713bbed467a977ec0d867ef53989ff374Dake Gu @Override 1279306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementStart(List<String> sharedElementNames, 1284121f22713bbed467a977ec0d867ef53989ff374Dake Gu List<View> sharedElements, List<View> sharedElementSnapshots) { 12999881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 13099881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "onSharedElementStart " + mActivityToRunTransition); 13199881f0d15df96179f93eee2d624b338d327571cDake Gu } 1324121f22713bbed467a977ec0d867ef53989ff374Dake Gu if (sharedElements.size() < 1) { 1334121f22713bbed467a977ec0d867ef53989ff374Dake Gu return; 1344121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 1354121f22713bbed467a977ec0d867ef53989ff374Dake Gu View overviewView = sharedElements.get(0); 136e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) { 1374121f22713bbed467a977ec0d867ef53989ff374Dake Gu return; 1384121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 139b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu View snapshot = sharedElementSnapshots.get(0); 140b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (hasImageViewScaleChange(snapshot)) { 141b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu saveImageViewScale(); 142b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu changeImageViewScale(snapshot); 143b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 1444121f22713bbed467a977ec0d867ef53989ff374Dake Gu View imageView = mViewHolder.mImageView; 1454121f22713bbed467a977ec0d867ef53989ff374Dake Gu final int width = overviewView.getWidth(); 1464121f22713bbed467a977ec0d867ef53989ff374Dake Gu final int height = overviewView.getHeight(); 1474121f22713bbed467a977ec0d867ef53989ff374Dake Gu imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 1484121f22713bbed467a977ec0d867ef53989ff374Dake Gu MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 1494121f22713bbed467a977ec0d867ef53989ff374Dake Gu imageView.layout(0, 0, width, height); 150b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu final View rightPanel = mViewHolder.mRightPanel; 1514121f22713bbed467a977ec0d867ef53989ff374Dake Gu if (mRightPanelWidth != 0 && mRightPanelHeight != 0) { 1524121f22713bbed467a977ec0d867ef53989ff374Dake Gu rightPanel.measure(MeasureSpec.makeMeasureSpec(mRightPanelWidth, MeasureSpec.EXACTLY), 1534121f22713bbed467a977ec0d867ef53989ff374Dake Gu MeasureSpec.makeMeasureSpec(mRightPanelHeight, MeasureSpec.EXACTLY)); 1544121f22713bbed467a977ec0d867ef53989ff374Dake Gu rightPanel.layout(width, rightPanel.getTop(), width + mRightPanelWidth, 1554121f22713bbed467a977ec0d867ef53989ff374Dake Gu rightPanel.getTop() + mRightPanelHeight); 1564121f22713bbed467a977ec0d867ef53989ff374Dake Gu } else { 1574121f22713bbed467a977ec0d867ef53989ff374Dake Gu rightPanel.offsetLeftAndRight(width - rightPanel.getLeft()); 1584121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 15972a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu mViewHolder.mActionsRow.setVisibility(View.INVISIBLE); 16072a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu mViewHolder.mDetailsDescriptionFrame.setVisibility(View.INVISIBLE); 161b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu } 162b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu 163b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu @Override 1649306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementEnd(List<String> sharedElementNames, 165b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu List<View> sharedElements, List<View> sharedElementSnapshots) { 16699881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 16799881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "onSharedElementEnd " + mActivityToRunTransition); 16899881f0d15df96179f93eee2d624b338d327571cDake Gu } 169b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu if (sharedElements.size() < 1) { 170b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu return; 171b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu } 172b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu View overviewView = sharedElements.get(0); 173e7b29b745f6562b43ad79074cf5445a26cd4073cDake Gu if (mViewHolder == null || mViewHolder.mOverviewFrame != overviewView) { 174b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu return; 175b0181a77ce38f75a7d218745a330c5d80daacfb6Dake Gu } 176b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu restoreImageViewScale(); 17795400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu // temporary let action row take focus so we defer button background animation 17895400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 17972a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu mViewHolder.mActionsRow.setVisibility(View.VISIBLE); 18095400e6d31a1ac09e48cb8944a79b7250484aa4cDake Gu mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 1819621fcb393357c42b15952a91c80350a798d99f4Dake Gu // switch focusability to VISIBLE wont trigger focusableViewAvailable() on O because 1829621fcb393357c42b15952a91c80350a798d99f4Dake Gu // shared element details_frame is still INVISIBLE. b/63544781 1839621fcb393357c42b15952a91c80350a798d99f4Dake Gu mViewHolder.mActionsRow.requestFocus(); 18472a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu mViewHolder.mDetailsDescriptionFrame.setVisibility(View.VISIBLE); 1854121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 1864121f22713bbed467a977ec0d867ef53989ff374Dake Gu 187d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu void setSharedElementEnterTransition(Activity activity, String sharedElementName, 188d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu long timeoutMs) { 189694edde99dc3782374977dab6d9aa34a16c13337Dake Gu if ((activity == null && !TextUtils.isEmpty(sharedElementName)) 190694edde99dc3782374977dab6d9aa34a16c13337Dake Gu || (activity != null && TextUtils.isEmpty(sharedElementName))) { 1914121f22713bbed467a977ec0d867ef53989ff374Dake Gu throw new IllegalArgumentException(); 1924121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 1933103f63e99d47573823957f7aa34308555873221Aurimas Liutikas if (activity == mActivityToRunTransition 1943103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && TextUtils.equals(sharedElementName, mSharedElementName)) { 1954121f22713bbed467a977ec0d867ef53989ff374Dake Gu return; 1964121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 1974121f22713bbed467a977ec0d867ef53989ff374Dake Gu if (mActivityToRunTransition != null) { 1989306f07b1d66f4974a81f781d29739b30124fff0George Mount ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, null); 1994121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2004121f22713bbed467a977ec0d867ef53989ff374Dake Gu mActivityToRunTransition = activity; 2014121f22713bbed467a977ec0d867ef53989ff374Dake Gu mSharedElementName = sharedElementName; 20299881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 20399881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "postponeEnterTransition " + mActivityToRunTransition); 20499881f0d15df96179f93eee2d624b338d327571cDake Gu } 20599881f0d15df96179f93eee2d624b338d327571cDake Gu ActivityCompat.setEnterSharedElementCallback(mActivityToRunTransition, this); 20699881f0d15df96179f93eee2d624b338d327571cDake Gu ActivityCompat.postponeEnterTransition(mActivityToRunTransition); 20799881f0d15df96179f93eee2d624b338d327571cDake Gu if (timeoutMs > 0) { 2082056c3e52465864d60f6f64c16a0a27629ba5fd8Dake Gu new Handler().postDelayed(new TransitionTimeOutRunnable(this), timeoutMs); 2094121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2104121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2114121f22713bbed467a977ec0d867ef53989ff374Dake Gu 2124121f22713bbed467a977ec0d867ef53989ff374Dake Gu void onBindToDrawable(ViewHolder vh) { 21399881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 21499881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "onBindToDrawable, could start transition of " + mActivityToRunTransition); 21599881f0d15df96179f93eee2d624b338d327571cDake Gu } 21699881f0d15df96179f93eee2d624b338d327571cDake Gu if (mViewHolder != null) { 21799881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 21899881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "rebind? clear transitionName on current viewHolder " 21999881f0d15df96179f93eee2d624b338d327571cDake Gu + mViewHolder.mOverviewFrame); 22099881f0d15df96179f93eee2d624b338d327571cDake Gu } 22199881f0d15df96179f93eee2d624b338d327571cDake Gu ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, null); 22299881f0d15df96179f93eee2d624b338d327571cDake Gu } 2234121f22713bbed467a977ec0d867ef53989ff374Dake Gu // After we got a image drawable, we can determine size of right panel. 2244121f22713bbed467a977ec0d867ef53989ff374Dake Gu // We want right panel to have fixed size so that the right panel don't change size 2254121f22713bbed467a977ec0d867ef53989ff374Dake Gu // when the overview is layout as a small bounds in transition. 2264121f22713bbed467a977ec0d867ef53989ff374Dake Gu mViewHolder = vh; 2274121f22713bbed467a977ec0d867ef53989ff374Dake Gu mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 2284121f22713bbed467a977ec0d867ef53989ff374Dake Gu @Override 2294121f22713bbed467a977ec0d867ef53989ff374Dake Gu public void onLayoutChange(View v, int left, int top, int right, int bottom, 2304121f22713bbed467a977ec0d867ef53989ff374Dake Gu int oldLeft, int oldTop, int oldRight, int oldBottom) { 2314121f22713bbed467a977ec0d867ef53989ff374Dake Gu mViewHolder.mRightPanel.removeOnLayoutChangeListener(this); 2324121f22713bbed467a977ec0d867ef53989ff374Dake Gu mRightPanelWidth = mViewHolder.mRightPanel.getWidth(); 2334121f22713bbed467a977ec0d867ef53989ff374Dake Gu mRightPanelHeight = mViewHolder.mRightPanel.getHeight(); 23499881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 23599881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "onLayoutChange records size of right panel as " 23699881f0d15df96179f93eee2d624b338d327571cDake Gu + mRightPanelWidth + ", "+ mRightPanelHeight); 23799881f0d15df96179f93eee2d624b338d327571cDake Gu } 2384121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2394121f22713bbed467a977ec0d867ef53989ff374Dake Gu }); 24099881f0d15df96179f93eee2d624b338d327571cDake Gu mViewHolder.mRightPanel.postOnAnimation(new Runnable() { 24199881f0d15df96179f93eee2d624b338d327571cDake Gu @Override 24299881f0d15df96179f93eee2d624b338d327571cDake Gu public void run() { 24399881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 24499881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "setTransitionName "+mViewHolder.mOverviewFrame); 24599881f0d15df96179f93eee2d624b338d327571cDake Gu } 24699881f0d15df96179f93eee2d624b338d327571cDake Gu ViewCompat.setTransitionName(mViewHolder.mOverviewFrame, mSharedElementName); 2478403619efebe94666c0615c3fc85080a303acf80Dake Gu Object transition = TransitionHelper.getSharedElementEnterTransition( 24899881f0d15df96179f93eee2d624b338d327571cDake Gu mActivityToRunTransition.getWindow()); 24999881f0d15df96179f93eee2d624b338d327571cDake Gu if (transition != null) { 2508403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.addTransitionListener(transition, new TransitionListener() { 25199881f0d15df96179f93eee2d624b338d327571cDake Gu @Override 25299881f0d15df96179f93eee2d624b338d327571cDake Gu public void onTransitionEnd(Object transition) { 25399881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 25499881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "onTransitionEnd " + mActivityToRunTransition); 255d391b19d1bf663ce300b0f4550e6fbaa7e12b0d4Dake Gu } 25699881f0d15df96179f93eee2d624b338d327571cDake Gu // after transition if the action row still focused, transfer 25799881f0d15df96179f93eee2d624b338d327571cDake Gu // focus to its children 25899881f0d15df96179f93eee2d624b338d327571cDake Gu if (mViewHolder.mActionsRow.isFocused()) { 25999881f0d15df96179f93eee2d624b338d327571cDake Gu mViewHolder.mActionsRow.requestFocus(); 26099881f0d15df96179f93eee2d624b338d327571cDake Gu } 2618403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.removeTransitionListener(transition, this); 26299881f0d15df96179f93eee2d624b338d327571cDake Gu } 26399881f0d15df96179f93eee2d624b338d327571cDake Gu }); 2644121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 26599881f0d15df96179f93eee2d624b338d327571cDake Gu startPostponedEnterTransition(); 26699881f0d15df96179f93eee2d624b338d327571cDake Gu } 26799881f0d15df96179f93eee2d624b338d327571cDake Gu }); 26899881f0d15df96179f93eee2d624b338d327571cDake Gu } 26999881f0d15df96179f93eee2d624b338d327571cDake Gu 27099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void startPostponedEnterTransition() { 27199881f0d15df96179f93eee2d624b338d327571cDake Gu if (!mStartedPostpone) { 27299881f0d15df96179f93eee2d624b338d327571cDake Gu if (DEBUG) { 27399881f0d15df96179f93eee2d624b338d327571cDake Gu Log.d(TAG, "startPostponedEnterTransition " + mActivityToRunTransition); 27499881f0d15df96179f93eee2d624b338d327571cDake Gu } 27599881f0d15df96179f93eee2d624b338d327571cDake Gu ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition); 27699881f0d15df96179f93eee2d624b338d327571cDake Gu mStartedPostpone = true; 2774121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2784121f22713bbed467a977ec0d867ef53989ff374Dake Gu } 2794121f22713bbed467a977ec0d867ef53989ff374Dake Gu} 280